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