Hermes2D  2.0
mesh_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 //
7 // Hermes2D is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation, either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // Hermes2D is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with Hermes2D. If not, see <http://www.gnu.org/licenses/>.
19 
20 // $Id: view4.cpp 1086 2008-10-21 09:05:44Z jakub $
21 
22 #ifndef NOGLUT
23 
24 #include <GL/freeglut.h>
25 #include "global.h"
26 #include "mesh_view.h"
27 
28 namespace Hermes
29 {
30  namespace Hermes2D
31  {
32  namespace Views
33  {
34  MeshView::MeshView(const char* title, WinGeom* wg)
35  : View(title, wg), lin(NULL)
36  {
37  nodes = elems = NULL;
38  b_scale = false;
39  b_ids = false;
40  b_markers = true;
41  b_elem_mrk = false;
42  }
43 
44  MeshView::MeshView(char* title, WinGeom* wg)
45  : View(title, wg), lin(NULL)
46  {
47  nodes = elems = NULL;
48  b_scale = false;
49  b_ids = false;
50  b_markers = true;
51  b_elem_mrk = false;
52  }
53 
54  MeshView::~MeshView()
55  {
56  if(nodes != NULL) delete [] nodes;
57  if(elems != NULL) delete [] elems;
58  if(lin != NULL)
59  delete this->lin;
60  }
61 
62  void MeshView::show(Mesh* mesh)
63  {
64  ZeroSolution<double> sln(mesh);
65  if(mesh == NULL) throw Hermes::Exceptions::Exception("mesh == NULL in MeshView::show().");
66  if(mesh->get_max_element_id() == 0) throw Hermes::Exceptions::Exception("Attempt to visualize empty mesh in MeshView::show().");
67 
68  this->mesh = mesh;
69 
70  if(lin == NULL)
71  lin = new Linearizer();
72 
73  lin->process_solution(&sln);
74  lin->lock_data();
75  lin->calc_vertices_aabb(&vertices_min_x, &vertices_max_x, &vertices_min_y, &vertices_max_y);
76  lin->unlock_data();
77 
78  int i;
79 
80  if(elems != NULL) delete [] elems;
81  ne = mesh->get_max_element_id() + 1;
82  elems = new ObjInfo[ne];
83  for (i = 0; i < ne; i++)
84  elems[i].id = -1;
85 
86  int active_element_cnt = 0;
87  float min_error = -1, max_error = -1;
88  Element* e;
89  for_all_active_elements(e, mesh)
90  {
91  ObjInfo* oi = elems + e->id;
92  oi->id = e->id;
93  oi->type = e->marker;
94  oi->x = oi->y = 0.0;
95  for (unsigned i = 0; i < e->get_nvert(); i++)
96  {
97  oi->x += e->vn[i]->x;
98  oi->y += e->vn[i]->y;
99  }
100  oi->x /= e->get_nvert();
101  oi->y /= e->get_nvert();
102  }
103 
104  create();
105  update_layout();
106  refresh();
107  reset_view(false);
108  wait_for_draw();
109  }
110 
111  void MeshView::set_b_elem_mrk(bool set)
112  {
113  if(b_ids)
114  b_ids = false;
115  b_elem_mrk = !b_elem_mrk;
116  refresh();
117  }
118 
119  void MeshView::on_display()
120  {
121  set_ortho_projection();
122  glDisable(GL_TEXTURE_1D);
123  glDisable(GL_LIGHTING);
124  glDisable(GL_DEPTH_TEST);
125 
126  // transform all vertices
127  lin->lock_data();
128  int i, nv = lin->get_num_vertices();
129  double3* vert = lin->get_vertices();
130  double2* tvert = new double2[nv];
131  for (i = 0; i < nv; i++)
132  {
133  tvert[i][0] = transform_x(vert[i][0]);
134  tvert[i][1] = transform_y(vert[i][1]);
135  }
136 
137  // draw all triangles
138  int3* tris = lin->get_triangles();
139  glColor3f(0.9f, 0.9f, 0.9f);
140  glBegin(GL_TRIANGLES);
141  for (i = 0; i < lin->get_num_triangles(); i++)
142  {
143  glVertex2d(tvert[tris[i][0]][0], tvert[tris[i][0]][1]);
144  glVertex2d(tvert[tris[i][1]][0], tvert[tris[i][1]][1]);
145  glVertex2d(tvert[tris[i][2]][0], tvert[tris[i][2]][1]);
146  }
147  glEnd();
148 
149  // draw all edges
150  glLineStipple(5, 0x5555);
151  int2* edges = lin->get_edges();
152  int* edge_markers = lin->get_edge_markers();
153  for (i = 0; i < lin->get_num_edges(); i++)
154  {
155  int mrk = b_markers ? edges[i][2] : 0;
156 
157  if(!edge_markers[i] &&
158  ((tvert[edges[i][0]][1] == tvert[edges[i][1]][1] &&
159  tvert[edges[i][0]][0] < tvert[edges[i][1]][0]) ||
160  tvert[edges[i][0]][1] < tvert[edges[i][1]][1])) continue;
161 
162  float* color = get_marker_color(mrk);
163  glColor3f(color[0], color[1], color[2]);
164  glLineWidth(mrk ? 1.5f : 1.0f);
165  glBegin(GL_LINES);
166  glVertex2d(tvert[edges[i][0]][0], tvert[edges[i][0]][1]);
167  glVertex2d(tvert[edges[i][1]][0], tvert[edges[i][1]][1]);
168  glEnd();
169 
170  if(mrk)
171  {
172  glEnable(GL_LINE_STIPPLE);
173  glColor3f(0.4f, 0.4f, 0.4f);
174  glBegin(GL_LINES);
175  glVertex2d(tvert[edges[i][0]][0], tvert[edges[i][0]][1]);
176  glVertex2d(tvert[edges[i][1]][0], tvert[edges[i][1]][1]);
177  glEnd();
178  glDisable(GL_LINE_STIPPLE);
179  }
180  }
181  glLineWidth(1.0);
182 
183  if(b_ids) // draw element ids
184  {
185  glColor3f(0, 0, 0);
186  for (i = 0; i < ne; i++)
187  {
188  if(elems[i].id < 0) continue;
189  char text[20];
190  sprintf(text, "#%d", elems[i].id);
191  draw_text(transform_x(elems[i].x), transform_y(elems[i].y), text, 0);
192  }
193  }
194  else if(b_elem_mrk) // draw element markers
195  {
196  glColor3f(0, 0, 0);
197  for (i = 0; i < ne; i++)
198  {
199  if(elems[i].id < 0) continue;
200  char text[2000];
201  sprintf(text, "%s", mesh->get_element_markers_conversion().get_user_marker(elems[i].type).marker.c_str());
202  draw_text(transform_x(elems[i].x), transform_y(elems[i].y), text, 0);
203  }
204  }
205 
206  delete [] tvert;
207  lin->unlock_data();
208  }
209 
210  void MeshView::on_key_down(unsigned char key, int x, int y)
211  {
212  switch (key)
213  {
214  case 'c':
215  reset_view(true);
216  refresh();
217  break;
218 
219  case 'b':
220  b_markers = !b_markers;
221  refresh();
222  break;
223 
224  case 'i':
225  if(b_elem_mrk) b_elem_mrk = false;
226  b_ids = !b_ids;
227  refresh();
228  break;
229 
230  case 'm':
231  if(b_ids) b_ids = false;
232  b_elem_mrk = !b_elem_mrk;
233  refresh();
234  break;
235 
236  default:
237  View::on_key_down(key, x, y);
238  break;
239  }
240  }
241 
242  float* MeshView::get_marker_color(int marker)
243  {
244  static float edgecol[3] = { 0.3f, 0.3f, 0.3f };
245  static float randcol[3];
246  static float mc[8][3] =
247  {
248  { 1.0f, 0.3f, 0.3f },
249  { 0.0f, 0.9f, 0.0f },
250  { 0.0f, 0.0f, 0.7f },
251  { 1.0f, 1.0f, 0.2f },
252  { 0.7f, 0.0f, 0.0f },
253  { 0.0f, 0.5f, 0.0f },
254  { 0.3f, 0.5f, 1.0f },
255  { 0.8f, 0.8f, 0.0f },
256  };
257 
258  if(marker == 0)
259  return edgecol;
260  else if(marker > 0 && marker < 8)
261  return mc[marker];
262  else
263  {
264  srand(marker + 2);
265  randcol[0] = (float) rand() / RAND_MAX;
266  randcol[1] = (float) rand() / RAND_MAX;
267  randcol[2] = (float) rand() / RAND_MAX;
268  return randcol;
269  }
270  }
271 
272  const char* MeshView::get_help_text() const
273  {
274  return
275  "MeshView\n"
276  "Controls:\n"
277  " Left mouse - pan\n"
278  " Right mouse - zoom\n"
279  " C - center image\n"
280  " H - render high-quality frame\n"
281  " B - toggle boundary markers\n"
282  " I - toggle element IDs\n"
283  " M - toggle element markers\n"
284  " S - save screenshot\n"
285  " F1 - this help\n"
286  " Esc, Q - quit";
287  }
288  }
289  }
290 }
291 #endif // NOGLUT