GLVis  v4.2
Accurate and flexible finite element visualization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
vssolution.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-443271.
4 //
5 // This file is part of the GLVis visualization tool and library. For more
6 // information and source code availability see https://glvis.org.
7 //
8 // GLVis is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #include <cstdlib>
13 #include <iostream>
14 #include <string>
15 #include <limits>
16 #include <cmath>
17 #include <vector>
18 
19 #include "mfem.hpp"
20 #include "visual.hpp"
21 #include "palettes.hpp"
22 #include "gltf.hpp"
23 
24 using namespace mfem;
25 using namespace std;
26 
27 
29 extern thread_local VisualizationScene *locscene;
30 extern thread_local GeometryRefiner GLVisGeometryRefiner;
31 
32 #ifdef GLVIS_ISFINITE
33 /* This test for INFs or NaNs is the same as the one used in hypre's PCG and
34  should work on all IEEE-compliant compilers. Fro detail see "Lecture Notes on
35  the Status of IEEE 754" by W. Kahan, http://tinyurl.com/cfz5d88 */
36 int isfinite(double x)
37 {
38  double ieee_check = 1;
39 
40  if (x != 0)
41  {
42  ieee_check = x/x; // INF -> NaN conversion
43  }
44 
45  return (ieee_check == ieee_check);
46 }
47 #endif
48 
49 // Definitions of some more keys
50 
52 {
53  std::stringstream os;
54  os << endl
55  << "+------------------------------------+" << endl
56  << "| Keys |" << endl
57  << "+------------------------------------+" << endl
58  << "| a - Displays/Hides the axes |" << endl
59  << "| A - Turns antialiasing on/off |" << endl
60  << "| b/B Toggle 2D boundary |" << endl
61  << "| c - Toggle colorbar and caption |" << endl
62  << "| C - Change the main plot caption |" << endl
63  << "| e - Displays/Hides the elements |" << endl
64  << "| f - Smooth/Nonconf/Flat shading |" << endl
65  << "| g - Toggle background |" << endl
66  << "| h - Displays help menu |" << endl
67  << "| i - Toggle the cutting plane |" << endl
68  << "| j - Turn on/off perspective |" << endl
69  << "| k/K Adjust the transparency level |" << endl
70  << "| ,/< Adjust color transparency |" << endl
71  << "| l - Turns on/off the light |" << endl
72  << "| L - Toggle logarithmic scale |" << endl
73  << "| m - Displays/Hides the mesh |" << endl
74  << "| n/N Cycle through numberings |" << endl
75  << "| o - (De)refine elem. (NC shading) |" << endl
76  << "| O - Switch 'o' func. (NC shading) |" << endl
77  << "| p/P Cycle through color palettes |" << endl
78  << "| q - Quits |" << endl
79  << "| r - Reset the plot to 3D view |" << endl
80  << "| R - Reset the plot to 2D view |" << endl
81  << "| s - Turn on/off unit cube scaling |" << endl
82  << "| S - Take snapshot/Record a movie |" << endl
83  << "| t - Cycle materials and lights |" << endl
84  << "| y/Y Rotate the cutting plane |" << endl
85  << "| z/Z Move the cutting plane |" << endl
86  << "| \\ - Set light source position |" << endl
87  << "| Ctrl+o - Element ordering curve |" << endl
88  << "| Ctrl+p - Print to a PDF file |" << endl
89  << "+------------------------------------+" << endl
90  << "| Function keys |" << endl
91  << "+------------------------------------+" << endl
92  << "| F1 - X window info and keystrokes |" << endl
93  << "| F2 - Update colors, etc. |" << endl
94  << "| F3/F4 - Shrink/Zoom elements |" << endl
95  << "| F5 - Set level lines |" << endl
96  << "| F6 - Palette options |" << endl
97  << "| F7 - Manually set min/max value |" << endl
98  << "| F8 - List of subdomains to show |" << endl
99  << "| F9/F10 - Walk through subdomains |" << endl
100  << "| F11/F12 - Shrink/Zoom subdomains |" << endl
101  << "+------------------------------------+" << endl
102  << "| Keypad |" << endl
103  << "+------------------------------------+" << endl
104  << "| 1-9 Small rotation, reset with 5 |" << endl
105  << "| *,/ Scale up/down |" << endl
106  << "| +/- Change z-scaling |" << endl
107  << "| . - Start/stop spinning |" << endl
108  << "| 0/Enter - Spinning speed and dir. |" << endl
109  << "+------------------------------------+" << endl
110  << "| Mouse |" << endl
111  << "+------------------------------------+" << endl
112  << "| left btn - Rotation |" << endl
113  << "| middle btn - Translation |" << endl
114  << "| right btn - Scaling |" << endl
115  << "| left + Alt - Tilt |" << endl
116  << "| left + Shift - Spinning |" << endl
117  << "| right + Shift - Change light pos. |" << endl
118  << "| left + Ctrl - Spherical rotation |" << endl
119  << "| middle+ Ctrl - Object translation |" << endl
120  << "| right + Ctrl - Object scaling |" << endl
121  << "| left + Ctrl + Shift - z-Spinning |" << endl
122  << "+------------------------------------+" << endl;
123  return os.str();
124 }
125 
126 static void KeyF8Pressed()
127 {
128  int attr;
129  Array<int> attr_list(&attr, 1);
130  const Array<int> &all_attr = vssol->GetMesh()->attributes;
131 
132  cout << "El attributes ON: ";
133  for (int i = 0; i < all_attr.Size(); i++)
134  if (vssol->el_attr_to_show[all_attr[i]-1])
135  {
136  cout << " " << all_attr[i];
137  }
138  cout << endl;
139 
140  cout << "El attribute to toggle : " << flush;
141  cin >> attr;
142  vssol->ToggleAttributes(attr_list);
143  SendExposeEvent();
144 }
145 
146 static void SwitchAttribute(int increment, int &attribute,
147  Array<int> &attribute_marker,
148  bool bdr)
149 {
150  const char *attr_type = bdr ? "bdr" : "element";
151  if (attribute_marker.Size() == 0)
152  {
153  cout << "There are no " << attr_type << " attributes" << endl;
154  return;
155  }
156  if (attribute == -1)
157  {
158  attribute_marker = 0;
159  attribute = (increment >= 0) ? 0 : attribute_marker.Size()-1;
160  }
161  else
162  {
163  if (attribute != attribute_marker.Size())
164  {
165  attribute_marker[attribute] = 0;
166  }
167  else
168  {
169  attribute_marker = 0;
170  }
171  attribute += increment;
172  }
173  attribute += attribute_marker.Size()+1;
174  attribute %= attribute_marker.Size()+1;
175  if (attribute != attribute_marker.Size())
176  {
177  attribute_marker[attribute] = 1;
178  cout << "Showing " << attr_type << " attribute " << attribute+1 << endl;
179  }
180  else
181  {
182  attribute_marker = 1;
183  cout << "Showing all " << attr_type << " attributes" << endl;
184  }
185  if (bdr)
186  {
188  }
189  else
190  {
191  vssol->PrepareLines();
192  vssol->Prepare();
193  }
194  SendExposeEvent();
195 }
196 
197 static void KeyF9Pressed(GLenum state)
198 {
199  if (!(state & KMOD_SHIFT))
200  {
201  SwitchAttribute(+1, vssol->attr_to_show, vssol->el_attr_to_show, false);
202  }
203  else
204  {
205  SwitchAttribute(+1, vssol->bdr_attr_to_show, vssol->bdr_el_attr_to_show,
206  true);
207  }
208 }
209 
210 static void KeyF10Pressed(GLenum state)
211 {
212  if (!(state & KMOD_SHIFT))
213  {
214  SwitchAttribute(-1, vssol->attr_to_show, vssol->el_attr_to_show, false);
215  }
216  else
217  {
218  SwitchAttribute(-1, vssol->bdr_attr_to_show, vssol->bdr_el_attr_to_show,
219  true);
220  }
221 }
222 
224 {
225  drawbdr = (drawbdr+1)%3;
226 
227  // Switch the colorbar range to correspond to the boundary attributes when
228  // showing them in color (drawbdr == 2) and restore it back when not.
229  if (drawbdr == 2)
230  {
231  if (drawelems == 1 || drawelems == 0)
232  {
233  minv_sol = minv;
234  maxv_sol = maxv;
235  have_sol_range = true;
236  }
237  drawelems = 0;
238  minv = 1;
239  maxv = mesh->bdr_attributes.Size() ? mesh->bdr_attributes.Max() : 1;
240  FixValueRange();
241  UpdateValueRange(true);
242  PrepareBoundary();
243  }
244  else if (drawbdr == 1)
245  {
246  PrepareBoundary();
247  }
248  else if (drawbdr == 0)
249  {
250  drawelems = 1;
251  if (have_sol_range)
252  {
253  minv = minv_sol;
254  maxv = maxv_sol;
255  bb.z[0] = minv;
256  bb.z[1] = maxv;
257  SetNewScalingFromBox(); // UpdateBoundingBox minus PrepareAxes
258  UpdateValueRange(true);
259  }
260  else
261  {
262  FindNewValueRange(true);
263  }
264  }
265 }
266 
267 static void KeyBPressed()
268 {
269  vssol -> ToggleDrawBdr();
270  SendExposeEvent();
271 }
272 
273 static void KeyMPressed()
274 {
275  vssol -> ToggleDrawMesh();
276  SendExposeEvent();
277 }
278 
279 static void KeyNPressed()
280 {
281  vssol -> ToggleDrawNumberings();
282  SendExposeEvent();
283 }
284 
285 static void KeyoPressed(GLenum state)
286 {
287  if (state & KMOD_CTRL)
288  {
289  vssol -> ToggleDrawOrdering();
290  vssol -> PrepareOrderingCurve();
291  SendExposeEvent();
292  }
293  else
294  {
296  }
297 }
298 
299 static void KeyOPressed(GLenum state)
300 {
301  (void)state;
303 }
304 
305 static void KeyEPressed()
306 {
307  vssol -> ToggleDrawElems();
308  SendExposeEvent();
309 }
310 
311 static void KeyFPressed()
312 {
313  vssol -> ToggleShading();
314  SendExposeEvent();
315 }
316 
318 {
319  vssol->ToggleDrawCP();
320  SendExposeEvent();
321 }
322 
324 {
325  // no-op, available
326 }
327 
328 static void KeyyPressed()
329 {
331  vssol->PrepareCP();
332  SendExposeEvent();
333 }
334 
335 static void KeyYPressed()
336 {
338  vssol->PrepareCP();
339  SendExposeEvent();
340 }
341 
342 static void KeyzPressed()
343 {
345  vssol->PrepareCP();
346  SendExposeEvent();
347 }
348 
349 static void KeyZPressed()
350 {
352  vssol->PrepareCP();
353  SendExposeEvent();
354 }
355 
356 static void KeyF3Pressed()
357 {
358  if (vssol->shading == 2)
359  {
360  vssol->shrink *= 0.9;
361  vssol->Prepare();
362  vssol->PrepareLines();
366  SendExposeEvent();
367  }
368 }
369 
370 static void KeyF4Pressed()
371 {
372  if (vssol->shading == 2)
373  {
374  vssol->shrink *= 1.11111111111111111111111;
375  vssol->Prepare();
376  vssol->PrepareLines();
379  SendExposeEvent();
380  }
381 }
382 
383 static void KeyF11Pressed()
384 {
385  if (vssol->shading == 2)
386  {
387  if (vssol->matc.Width() == 0)
388  {
390  }
391  vssol->shrinkmat *= 0.9;
392  vssol->Prepare();
393  vssol->PrepareLines();
397  SendExposeEvent();
398  }
399 }
400 
401 static void KeyF12Pressed()
402 {
403  if (vssol->shading == 2)
404  {
405  if (vssol->matc.Width() == 0)
406  {
408  }
409  vssol->shrinkmat *= 1.11111111111111111111111;
410  vssol->Prepare();
411  vssol->PrepareLines();
415  SendExposeEvent();
416  }
417 }
418 
420 {
421  v_normals = NULL;
422 }
423 
425  Mesh &m, Vector &s, Vector *normals)
426 {
427  mesh = &m;
428  sol = &s;
429  v_normals = normals;
430 
431  Init();
432 }
433 
435 {
436  rsol = NULL;
437  vssol = this;
438 
439  drawelems = shading = 1;
440  drawmesh = 0;
441  draworder = 0;
442  drawnums = 0;
443 
444  refine_func = 0;
445  have_sol_range = false;
446 
447  shrink = 1.0;
448  shrinkmat = 1.0;
449  bdrc.SetSize(2,0);
450  matc.SetSize(2,0);
451 
452  TimesToRefine = EdgeRefineFactor = 1;
453 
454  attr_to_show = bdr_attr_to_show = -1;
455  el_attr_to_show.SetSize(mesh->attributes.Max());
456  el_attr_to_show = 1;
457  bdr_el_attr_to_show.SetSize(mesh->bdr_attributes.Size() > 0 ?
458  mesh->bdr_attributes.Max() : 0);
459  bdr_el_attr_to_show = 1;
460 
461  drawbdr = 0;
462 
463  VisualizationSceneScalarData::Init(); // Calls FindNewBox() !!!
464 
465  palette.SetIndex(2); // use the 'jet-like' palette in 2D
466 
467  double eps = 1e-6; // move the cutting plane a bit to avoid artifacts
468  CuttingPlane = new Plane(-1.0,0.0,0.0,(0.5-eps)*bb.x[0]+(0.5+eps)*bb.x[1]);
469  draw_cp = 0;
470 
471  // static int init = 0;
472  // if (!init)
473  {
474  // init = 1;
475 
478 
479  wnd->setOnKeyDown('m', KeyMPressed);
480  wnd->setOnKeyDown('M', KeyMPressed);
481 
484 
485  wnd->setOnKeyDown('o', KeyoPressed);
486  wnd->setOnKeyDown('O', KeyOPressed);
487 
488  wnd->setOnKeyDown('e', KeyEPressed);
489  wnd->setOnKeyDown('E', KeyEPressed);
490 
491  wnd->setOnKeyDown('f', KeyFPressed);
492  wnd->setOnKeyDown('F', KeyFPressed);
493 
496 
497  wnd->setOnKeyDown('y', KeyyPressed);
498  wnd->setOnKeyDown('Y', KeyYPressed);
499  wnd->setOnKeyDown('z', KeyzPressed);
500  wnd->setOnKeyDown('Z', KeyZPressed);
501 
502  wnd->setOnKeyDown(SDLK_F3, KeyF3Pressed);
503  wnd->setOnKeyDown(SDLK_F4, KeyF4Pressed);
504  wnd->setOnKeyDown(SDLK_F8, KeyF8Pressed);
505  wnd->setOnKeyDown(SDLK_F9, KeyF9Pressed);
506  wnd->setOnKeyDown(SDLK_F10, KeyF10Pressed);
507  wnd->setOnKeyDown(SDLK_F11, KeyF11Pressed);
508  wnd->setOnKeyDown(SDLK_F12, KeyF12Pressed);
509  }
510 
511  Prepare();
512  PrepareLines();
513  PrepareLevelCurves();
514  PrepareBoundary();
515  PrepareNumbering();
516  PrepareOrderingCurve();
517 }
518 
520 {
521 }
522 
524 {
525  const char *modes[] =
526  {
527  "none", "solution", "kappa + 1/kappa", "kappa", "1/det(J)", "det(J)",
528  "attribute"
529  };
530 
531  if (drawbdr == 2) { return; }
532 
533  drawelems = (drawelems + 6) % 7;
534 
535  cout << "Surface elements mode : " << modes[drawelems] << endl;
536  if (drawelems < 2)
537  {
538  extra_caption.clear();
539  }
540  else
541  {
542  extra_caption = modes[drawelems];
543  }
544 
545  if (drawelems == 0)
546  {
547  minv_sol = minv;
548  maxv_sol = maxv;
549  have_sol_range = true;
550  }
551  else if (shading == 2)
552  {
553  if (drawelems == 1 && have_sol_range)
554  {
555  minv = minv_sol;
556  maxv = maxv_sol;
557  bb.z[0] = minv;
558  bb.z[1] = maxv;
559  SetNewScalingFromBox(); // UpdateBoundingBox minus PrepareAxes
560  UpdateValueRange(false);
561  }
562  else
563  {
564  DoAutoscaleValue(false);
565  }
566  PrepareLines();
567  PrepareBoundary();
568  Prepare();
569  PrepareLevelCurves();
570  PrepareCP();
571  PrepareNumbering();
572  }
573 }
574 
576  Mesh *new_m, Vector *new_sol, GridFunction *new_u)
577 {
578  // If the number of elements changes, recompute the refinement factor
579  if (mesh->GetNE() != new_m->GetNE())
580  {
581  mesh = new_m;
582  int ref = GetAutoRefineFactor();
583  if (TimesToRefine != ref || EdgeRefineFactor != 1)
584  {
585  TimesToRefine = ref;
586  EdgeRefineFactor = 1;
587  cout << "Subdivision factors = " << TimesToRefine << ", 1" << endl;
588  }
589  }
590  mesh = new_m;
591  sol = new_sol;
592  rsol = new_u;
593 
594  have_sol_range = false;
595  DoAutoscale(false);
596 
597  Prepare();
598  PrepareLines();
599  PrepareLevelCurves();
600  PrepareBoundary();
601  PrepareCP();
602  PrepareNumbering();
603  PrepareOrderingCurve();
604 }
605 
606 
608  int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr)
609 {
610  int geom = mesh->GetElementBaseGeometry(i);
611  ElementTransformation *T = mesh->GetElementTransformation(i);
612  double Jd[4];
613  DenseMatrix J(Jd, 2, 2);
614 
615  T->Transform(ir, tr);
616 
617  vals.SetSize(ir.GetNPoints());
618  for (int j = 0; j < ir.GetNPoints(); j++)
619  {
620  T->SetIntPoint(&ir.IntPoint(j));
621  Geometries.JacToPerfJac(geom, T->Jacobian(), J);
622  if (drawelems == 6) // attribute
623  {
624  vals(j) = mesh->GetAttribute(i);
625  }
626  else if (drawelems >= 4)
627  {
628  vals(j) = J.Det();
629  // if (vals(j) >= 0.0)
630  // vals(j) = sqrt(vals(j));
631  // else
632  // vals(j) = -sqrt(-vals(j));
633  }
634  else
635  {
636  vals(j) = J.CalcSingularvalue(0)/J.CalcSingularvalue(1);
637  if (drawelems == 2)
638  {
639  vals(j) = vals(j) + 1.0/vals(j);
640  }
641  }
642  }
643 
644  if (drawelems == 4)
645  {
646  for (int j = 0; j < vals.Size(); j++)
647  {
648  if (vals(j) <= 0.0)
649  {
650  vals = 0.0;
651  break;
652  }
653  vals(j) = 1.0 / vals(j);
654  }
655  }
656 
657  J.ClearExternalData();
658 }
659 
661  int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr)
662 {
663  if (drawelems < 2)
664  {
665  rsol->GetValues(i, ir, vals, tr);
666  }
667  else
668  {
669  GetRefinedDetJ(i, ir, vals, tr);
670  }
671 
672  if (logscale)
673  for (int j = 0; j < vals.Size(); j++)
674  {
675  vals(j) = _LogVal(vals(j));
676  }
677 
678  if (shrink != 1.0 || shrinkmat != 1.0)
679  {
680  ShrinkPoints(tr, i, 0, 0);
681  }
682 }
683 
685  int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr,
686  DenseMatrix &normals)
687 {
688  int have_normals = 0;
689 
690  if (drawelems < 2)
691  {
692  rsol->GetGradients(i, ir, tr);
693  normals.SetSize(3, tr.Width());
694  for (int j = 0; j < tr.Width(); j++)
695  {
696  normals(0, j) = -tr(0, j);
697  normals(1, j) = -tr(1, j);
698  normals(2, j) = 1.;
699  }
700  have_normals = 1;
701  rsol->GetValues(i, ir, vals, tr);
702  }
703  else
704  {
705  GetRefinedDetJ(i, ir, vals, tr);
706  }
707 
708  if (logscale)
709  {
710  if (have_normals)
711  {
712  for (int j = 0; j < normals.Width(); j++)
713  {
714  if (vals(j) >= minv && vals(j) <= maxv)
715  {
716  normals(0, j) *= log_a/vals(j);
717  normals(1, j) *= log_a/vals(j);
718  }
719  }
720  }
721  for (int j = 0; j < vals.Size(); j++)
722  {
723  vals(j) = _LogVal(vals(j));
724  }
725  }
726 
727  if (shrink != 1.0 || shrinkmat != 1.0)
728  {
729  ShrinkPoints(tr, i, 0, 0);
730  if (have_normals)
731  {
732  for (int j = 0; j < tr.Width(); j++)
733  {
734  normals(0, j) /= shrink;
735  normals(1, j) /= shrink;
736  }
737  }
738  }
739 
740  return have_normals;
741 }
742 
744 {
745  if (shading == s || s < 0)
746  {
747  return;
748  }
749 
750  if (rsol)
751  {
752  if (s > 2)
753  {
754  return;
755  }
756 
757  if (s == 2 || shading == 2)
758  {
759  shading = s;
760  have_sol_range = false;
761  DoAutoscale(false);
762  PrepareLines();
763  PrepareBoundary();
764  PrepareLevelCurves();
765  PrepareCP();
766  PrepareNumbering();
767  PrepareOrderingCurve();
768  }
769  else
770  {
771  shading = s;
772  }
773  }
774  else
775  {
776  if (s > 1)
777  {
778  return;
779  }
780  shading = s;
781  }
782  Prepare();
783 
784  static const char *shading_type[3] =
785  {"flat", "smooth", "non-conforming (with subdivision)"};
786  if (print)
787  {
788  cout << "Shading type : " << shading_type[shading] << endl;
789  }
790 }
791 
793 {
794  if (rsol)
795  {
796  SetShading((shading + 1) % 3, true);
797  }
798  else
799  {
800  SetShading(1 - shading, true);
801  }
802 }
803 
805 {
806  int update = 1;
807  switch (refine_func)
808  {
809  case 0:
810  TimesToRefine += EdgeRefineFactor;
811  break;
812  case 1:
813  if (TimesToRefine > EdgeRefineFactor)
814  {
815  TimesToRefine -= EdgeRefineFactor;
816  }
817  else
818  {
819  update = 0;
820  }
821  break;
822  case 2:
823  TimesToRefine /= EdgeRefineFactor;
824  EdgeRefineFactor++;
825  TimesToRefine *= EdgeRefineFactor;
826  break;
827  case 3:
828  if (EdgeRefineFactor > 1)
829  {
830  TimesToRefine /= EdgeRefineFactor;
831  EdgeRefineFactor--;
832  TimesToRefine *= EdgeRefineFactor;
833  }
834  else
835  {
836  update = 0;
837  }
838  break;
839  }
840  if (update && shading == 2)
841  {
842  have_sol_range = false;
843  DoAutoscale(false);
844  PrepareLines();
845  PrepareBoundary();
846  Prepare();
847  PrepareLevelCurves();
848  PrepareCP();
849  SendExposeEvent();
850  }
851  cout << "Subdivision factors = " << TimesToRefine << ", " << EdgeRefineFactor
852  << endl;
853 }
854 
856 {
857  refine_func = (refine_func+1)%4;
858  cout << "Key 'o' will: ";
859  switch (refine_func)
860  {
861  case 0:
862  cout << "Increase subdivision factor" << endl;
863  break;
864  case 1:
865  cout << "Decrease subdivision factor" << endl;
866  break;
867  case 2:
868  cout << "Increase bdr subdivision factor" << endl;
869  break;
870  case 3:
871  cout << "Decrease bdr subdivision factor" << endl;
872  break;
873  }
874 }
875 
877 {
878  if ((tot == TimesToRefine && bdr == EdgeRefineFactor) || tot < 1 || bdr < 1)
879  {
880  return;
881  }
882 
883  if (tot % bdr)
884  {
885  tot += bdr - tot % bdr;
886  }
887 
888  TimesToRefine = tot;
889  EdgeRefineFactor = bdr;
890 
891  if (shading == 2)
892  {
893  have_sol_range = false;
894  DoAutoscale(false);
895  PrepareLines();
896  PrepareBoundary();
897  Prepare();
898  PrepareLevelCurves();
899  PrepareCP();
900  }
901 }
902 
904 {
905  int ne = mesh->GetNE(), ref = 1;
906 
907  while (ref < auto_ref_max && ne*(ref+1)*(ref+1) <= auto_ref_max_surf_elem)
908  {
909  ref++;
910  }
911 
912  return ref;
913 }
914 
916 {
917  int ref = GetAutoRefineFactor();
918 
919  cout << "Subdivision factors = " << ref << ", 1" << endl;
920 
921  SetRefineFactors(ref, 1);
922 }
923 
925 {
926  Array<int> &attr_marker = el_attr_to_show;
927 
928  for (int i = 0; i < attr_list.Size(); i++)
929  {
930  int attr = attr_list[i];
931  if (attr < 1)
932  {
933  cout << "Hiding all attributes." << endl;
934  attr_marker = 0;
935  }
936  else if (attr > attr_marker.Size())
937  {
938  cout << "Showing all attributes." << endl;
939  attr_marker = 1;
940  }
941  else
942  {
943  attr_marker[attr-1] = !attr_marker[attr-1];
944  }
945  }
946  PrepareLines();
947  Prepare();
948 }
949 
951 {
952  if (scaling)
953  {
955  }
956  else
957  {
958  xscale = bb.x[1]-bb.x[0];
959  yscale = bb.y[1]-bb.y[0];
960  zscale = bb.z[1]-bb.z[0];
961  xscale = (xscale < yscale) ? yscale : xscale;
962  xscale = (xscale > 0.0) ? ( 1.0 / xscale ) : 1.0;
963  yscale = xscale;
964  zscale = (zscale > 0.0) ? ( 1.0 / zscale ) : 1.0;
965  }
966  zscale /= ((1. + sqrt(5.)) / 2.);
967 }
968 
969 void VisualizationSceneSolution::FindNewBox(double rx[], double ry[],
970  double rval[])
971 {
972  int i, j;
973 
974  if (shading != 2)
975  {
976  int nv = mesh -> GetNV();
977 
978  double *coord = mesh->GetVertex(0);
979 
980  rval[0] = rval[1] = (*sol)(0);
981  for (i = 1; i < sol->Size(); i++)
982  {
983  if ((*sol)(i) < rval[0]) { rval[0] = (*sol)(i); }
984  if ((*sol)(i) > rval[1]) { rval[1] = (*sol)(i); }
985  }
986  rx[0] = rx[1] = coord[0];
987  ry[0] = ry[1] = coord[1];
988 
989  for (i = 1; i < nv; i++)
990  {
991  coord = mesh->GetVertex(i);
992  if (coord[0] < rx[0]) { rx[0] = coord[0]; }
993  if (coord[1] < ry[0]) { ry[0] = coord[1]; }
994  if (coord[0] > rx[1]) { rx[1] = coord[0]; }
995  if (coord[1] > ry[1]) { ry[1] = coord[1]; }
996  }
997  }
998  else
999  {
1000  int ne = mesh -> GetNE();
1001  DenseMatrix pointmat;
1002  Vector values;
1003  RefinedGeometry *RefG;
1004  bool log_scale = logscale;
1005 
1006  logscale = false;
1007  rx[0] = ry[0] = rval[0] = numeric_limits<double>::infinity();
1008  rx[1] = ry[1] = rval[1] = -rx[0];
1009  for (i = 0; i < ne; i++)
1010  {
1011  RefG = GLVisGeometryRefiner.Refine(mesh->GetElementBaseGeometry(i),
1012  TimesToRefine, EdgeRefineFactor);
1013  GetRefinedValues(i, RefG->RefPts, values, pointmat);
1014  for (j = 0; j < values.Size(); j++)
1015  {
1016  if (isfinite(pointmat(0,j)))
1017  {
1018  if (pointmat(0,j) < rx[0]) { rx[0] = pointmat(0,j); }
1019  if (pointmat(0,j) > rx[1]) { rx[1] = pointmat(0,j); }
1020  }
1021  if (isfinite(pointmat(1,j)))
1022  {
1023  if (pointmat(1,j) < ry[0]) { ry[0] = pointmat(1,j); }
1024  if (pointmat(1,j) > ry[1]) { ry[1] = pointmat(1,j); }
1025  }
1026  if (isfinite(values(j)))
1027  {
1028  if (values(j) < rval[0]) { rval[0] = values(j); }
1029  if (values(j) > rval[1]) { rval[1] = values(j); }
1030  }
1031  }
1032  }
1033  logscale = log_scale;
1034  }
1035 }
1036 
1038 {
1039  FindNewBox(bb.x, bb.y, bb.z);
1040 
1041  minv = bb.z[0];
1042  maxv = bb.z[1];
1043 
1044  FixValueRange();
1045 
1046  bb.z[0] = minv;
1047  bb.z[1] = maxv;
1048 
1049  SetNewScalingFromBox(); // UpdateBoundingBox minus PrepareAxes
1050  UpdateValueRange(prepare);
1051 }
1052 
1054 {
1055  double rx[2], ry[2], rv[2];
1056 
1057  FindNewBox(rx, ry, rv);
1058  minv = rv[0];
1059  maxv = rv[1];
1060 
1061  FixValueRange();
1062 
1063  UpdateValueRange(prepare);
1064 }
1065 
1067 {
1068  double rv[2];
1069 
1070  FindNewBox(bb.x, bb.y, rv);
1071 
1072  UpdateBoundingBox(); // SetNewScalingFromBox plus PrepareAxes
1073 }
1074 
1076 {
1077  if (logscale || LogscaleRange())
1078  {
1079  // we do not change the palette logscale setting here. It is set to 0 in
1080  // Prepare() since we apply logarithmic scaling to the values.
1081  // In PrepareVectorField() we call 'palette.SetUseLogscale(logscale)'.
1082  logscale = !logscale;
1083  SetLogA();
1084  SetLevelLines(minv, maxv, nl);
1085  EventUpdateColors(); // Prepare() [+ PrepareVectorField() for vectors]
1086  PrepareLines();
1087  PrepareLevelCurves();
1088  PrepareBoundary();
1089  PrepareCP();
1090  if (print)
1091  {
1092  PrintLogscale(false);
1093  }
1094  }
1095  else if (print)
1096  {
1097  PrintLogscale(true);
1098  }
1099 }
1100 
1102 {
1103  Prepare();
1104  PrepareOrderingCurve();
1105 }
1106 
1108 {
1109  PrepareNumbering();
1110 }
1111 
1112 void DrawNumberedMarker(gl3::GlDrawable& buff, const double x[3], double dx,
1113  int n)
1114 {
1115  gl3::GlBuilder bld = buff.createBuilder();
1116  bld.glBegin(GL_LINES);
1117  // glColor4d(0, 0, 0, 0);
1118  bld.glVertex3d(x[0]-dx, x[1]-dx, x[2]);
1119  bld.glVertex3d(x[0]+dx, x[1]+dx, x[2]);
1120  bld.glVertex3d(x[0]+dx, x[1]-dx, x[2]);
1121  bld.glVertex3d(x[0]-dx, x[1]+dx, x[2]);
1122  bld.glEnd();
1123 
1124  buff.addText(x[0], x[1], x[2], std::to_string(n));
1125 }
1126 
1127 void RemoveFPErrors(const DenseMatrix &pts, Vector &vals, DenseMatrix &normals,
1128  const int n, const Array<int> &ind, Array<int> &f_ind)
1129 {
1130  int o = 0;
1131 
1132  f_ind.SetSize(ind.Size());
1133  for (int i = 0; i < ind.Size(); i += n)
1134  {
1135  bool good = true;
1136  for (int j = 0; j < n; j++)
1137  {
1138  f_ind[o+j] = ind[i+j];
1139 
1140  if (!isfinite(pts(0, ind[i+j])) || !isfinite(pts(1, ind[i+j])) ||
1141  !isfinite(pts(2, ind[i+j])) || !isfinite(vals(ind[i+j])))
1142  // check normals?
1143  {
1144  good = false;
1145  break;
1146  }
1147  }
1148  if (good)
1149  {
1150  o += n;
1151  }
1152  }
1153  f_ind.SetSize(o);
1154 }
1155 
1157 {
1158  disp_buf.clear();
1159  gl3::GlBuilder poly = disp_buf.createBuilder();
1160  Array<int> vertices;
1161  double *vtx, *nor, val, s;
1162 
1163  for (int i = 0; i < mesh->GetNE(); i++)
1164  {
1165  if (!el_attr_to_show[mesh->GetAttribute(i)-1]) { continue; }
1166 
1167  mesh->GetElementVertices(i, vertices);
1168  GLenum shape;
1169  if (vertices.Size() == 3)
1170  {
1171  shape = GL_TRIANGLES;
1172  }
1173  else
1174  {
1175  shape = GL_QUADS;
1176  }
1177  poly.glBegin(shape);
1178  for (int j = 0; j < vertices.Size(); j++)
1179  {
1180  vtx = mesh->GetVertex(vertices[j]);
1181  nor = &(*v_normals)(3*vertices[j]);
1182  val = (*sol)(vertices[j]);
1183  if (logscale && val >= minv && val <= maxv)
1184  {
1185  s = log_a/val;
1186  val = _LogVal_(val);
1187  poly.glNormal3d(s*nor[0], s*nor[1], nor[2]);
1188  }
1189  else
1190  {
1191  poly.glNormal3dv(nor);
1192  }
1193  MySetColor(poly, val, minv, maxv);
1194  poly.glVertex3d(vtx[0], vtx[1], val);
1195  }
1196  poly.glEnd();
1197  }
1198  updated_bufs.emplace_back(&disp_buf);
1199 }
1200 
1202 {
1203  int i, j;
1204  disp_buf.clear();
1205  int ne = mesh -> GetNE();
1206  DenseMatrix pointmat;
1207  Array<int> vertices;
1208  double pts[4][3], col[4];
1209 
1210  for (i = 0; i < ne; i++)
1211  {
1212  if (!el_attr_to_show[mesh->GetAttribute(i)-1]) { continue; }
1213 
1214  mesh->GetPointMatrix (i, pointmat);
1215  mesh->GetElementVertices (i, vertices);
1216 
1217  for (j = 0; j < pointmat.Width(); j++)
1218  {
1219  pts[j][0] = pointmat(0, j);
1220  pts[j][1] = pointmat(1, j);
1221  pts[j][2] = col[j] = LogVal((*sol)(vertices[j]));
1222  }
1223  if (j == 3)
1224  {
1225  DrawTriangle(disp_buf, pts, col, minv, maxv);
1226  }
1227  else
1228  {
1229  DrawQuad(disp_buf, pts, col, minv, maxv);
1230  }
1231  }
1232  updated_bufs.emplace_back(&disp_buf);
1233 }
1234 
1235 // determines how quads and their level lines are drawn
1236 // when using subdivision:
1237 // 0 - draw a quad
1238 // 1 - draw 2 triangles (split using the '0-2' diagonal)
1239 // 2 - draw 4 triangles (split using both diagonals)
1240 const int split_quads = 1;
1241 
1243 {
1244  int i, j, k;
1245  disp_buf.clear();
1246  int ne = mesh -> GetNE();
1247  DenseMatrix pointmat, pts3d, normals;
1248  Vector values;
1249  RefinedGeometry *RefG;
1250  Array<int> fRG;
1251 
1252  for (i = 0; i < ne; i++)
1253  {
1254  if (!el_attr_to_show[mesh->GetAttribute(i)-1]) { continue; }
1255 
1256  RefG = GLVisGeometryRefiner.Refine(mesh->GetElementBaseGeometry(i),
1257  TimesToRefine, EdgeRefineFactor);
1258  j = GetRefinedValuesAndNormals(i, RefG->RefPts, values, pointmat,
1259  normals);
1260  Array<int> &RG = RefG->RefGeoms;
1261  int sides = mesh->GetElement(i)->GetNVertices();
1262 
1263 #if 1
1264  pts3d.SetSize(3, pointmat.Width());
1265  for (k = 0; k < pointmat.Width(); k++)
1266  {
1267  pts3d(0, k) = pointmat(0, k);
1268  pts3d(1, k) = pointmat(1, k);
1269  pts3d(2, k) = values(k);
1270  }
1271  j = (j != 0) ? 2 : 0;
1272  RemoveFPErrors(pts3d, values, normals, sides, RG, fRG);
1273  DrawPatch(disp_buf, pts3d, values, normals, sides, fRG, minv, maxv, j);
1274 #else
1275  for (k = 0; k < RG.Size()/sides; k++)
1276  {
1277  int *ind = &RG[sides*k];
1278  if (split_quads == 0 || sides == 3)
1279  {
1280  for (j = 0; j < sides; j++)
1281  {
1282  pts[j][0] = pointmat(0, ind[j]);
1283  pts[j][1] = pointmat(1, ind[j]);
1284  pts[j][2] = col[j] = values(ind[j]);
1285  }
1286  if (sides == 3)
1287  {
1288  DrawTriangle(pts, col, minv, maxv);
1289  }
1290  else
1291  {
1292  DrawQuad(pts, col, minv, maxv);
1293  }
1294  }
1295  else if (split_quads == 1)
1296  {
1297  // draw 2 triangles for each quad
1298  // (split with the 0-2 diagonal)
1299  const int vt[2][3] = {{ 0, 1, 2 }, { 2, 3, 0 }};
1300  for (int it = 0; it < 2; it++)
1301  {
1302  for (j = 0; j < 3; j++)
1303  {
1304  pts[j][0] = pointmat(0, ind[vt[it][j]]);
1305  pts[j][1] = pointmat(1, ind[vt[it][j]]);
1306  pts[j][2] = col[j] = values(ind[vt[it][j]]);
1307  }
1308  DrawTriangle(pts, col, minv, maxv);
1309  }
1310  }
1311  else
1312  {
1313  // draw 4 triangles for each quad
1314  // (split with both diagonals)
1315  pts[2][0] = pts[2][1] = pts[2][2] = 0.0;
1316  for (j = 0; j < 4; j++)
1317  {
1318  pts[2][0] += pointmat(0, ind[j]);
1319  pts[2][1] += pointmat(1, ind[j]);
1320  pts[2][2] += values(ind[j]);
1321  }
1322  pts[2][0] *= 0.25;
1323  pts[2][1] *= 0.25;
1324  pts[2][2] *= 0.25;
1325  col[2] = pts[2][2];
1326  for (j = 0; j < 4; j++)
1327  {
1328  pts[0][0] = pointmat(0, ind[j]);
1329  pts[0][1] = pointmat(1, ind[j]);
1330  pts[0][2] = col[0] = values(ind[j]);
1331  int l = (j+1)%4;
1332  pts[1][0] = pointmat(0, ind[l]);
1333  pts[1][1] = pointmat(1, ind[l]);
1334  pts[1][2] = col[1] = values(ind[l]);
1335  DrawTriangle(pts, col, minv, maxv);
1336  }
1337  }
1338  }
1339 #endif
1340  }
1341  updated_bufs.emplace_back(&disp_buf);
1342 }
1343 
1345 {
1346  palette.SetUseLogscale(0);
1347 
1348  switch (shading)
1349  {
1350  case 0:
1351  PrepareFlat();
1352  return;
1353  case 2:
1354  PrepareFlat2();
1355  return;
1356  default:
1357  if (v_normals)
1358  {
1359  PrepareWithNormals();
1360  return;
1361  }
1362  break;
1363  }
1364 
1365  int i, j;
1366 
1367  disp_buf.clear();
1368  gl3::GlBuilder poly = disp_buf.createBuilder();
1369  int ne = mesh -> GetNE();
1370  int nv = mesh -> GetNV();
1371  DenseMatrix pointmat;
1372  Array<int> vertices;
1373  double p[4][3], nor[3];
1374 
1375  Vector nx(nv);
1376  Vector ny(nv);
1377  Vector nz(nv);
1378 
1379  for (int d = 0; d < mesh -> attributes.Size(); d++)
1380  {
1381 
1382  if (!el_attr_to_show[mesh -> attributes[d]-1]) { continue; }
1383 
1384  nx = 0.;
1385  ny = 0.;
1386  nz = 0.;
1387 
1388  for (i = 0; i < ne; i++)
1389  if (mesh -> GetAttribute(i) == mesh -> attributes[d])
1390  {
1391  mesh->GetPointMatrix (i, pointmat);
1392  mesh->GetElementVertices (i, vertices);
1393 
1394  for (j = 0; j < pointmat.Size(); j++)
1395  {
1396  p[j][0] = pointmat(0, j);
1397  p[j][1] = pointmat(1, j);
1398  p[j][2] = LogVal((*sol)(vertices[j]));
1399  }
1400 
1401  if (pointmat.Width() == 3)
1402  {
1403  j = Compute3DUnitNormal(p[0], p[1], p[2], nor);
1404  }
1405  else
1406  {
1407  j = Compute3DUnitNormal(p[0], p[1], p[2], p[3], nor);
1408  }
1409 
1410  if (j == 0)
1411  for (j = 0; j < pointmat.Size(); j++)
1412  {
1413  nx(vertices[j]) += nor[0];
1414  ny(vertices[j]) += nor[1];
1415  nz(vertices[j]) += nor[2];
1416  }
1417  }
1418 
1419  for (i = 0; i < ne; i++)
1420  {
1421  if (mesh -> GetAttribute(i) == mesh -> attributes[d])
1422  {
1423  GLenum shape = GL_NONE;
1424  switch (mesh->GetElementType(i))
1425  {
1426  case Element::TRIANGLE:
1427  shape = GL_TRIANGLES;
1428  break;
1429  case Element::QUADRILATERAL:
1430  shape = GL_QUADS;
1431  break;
1432  default:
1433  MFEM_ABORT("Invalid 2D element type");
1434  break;
1435  }
1436  poly.glBegin(shape);
1437  mesh->GetPointMatrix (i, pointmat);
1438  mesh->GetElementVertices (i, vertices);
1439 
1440  for (j = 0; j < pointmat.Size(); j++)
1441  {
1442  double z = LogVal((*sol)(vertices[j]));
1443  MySetColor(poly, z, minv, maxv);
1444  poly.glNormal3d(nx(vertices[j]), ny(vertices[j]), nz(vertices[j]));
1445  poly.glVertex3d(pointmat(0, j), pointmat(1, j), z);
1446  }
1447  poly.glEnd();
1448  }
1449  }
1450  }
1451  updated_bufs.emplace_back(&disp_buf);
1452 }
1453 
1455 {
1456  if (shading == 2)
1457  {
1458  PrepareLevelCurves2();
1459  return;
1460  }
1461 
1462  static int vt[4] = { 0, 1, 2, 3 };
1463  Array<int> RG(vt, 4), vertices;
1464  Vector values;
1465  DenseMatrix pointmat;
1466 
1467  lcurve_buf.clear();
1468  gl3::GlBuilder build = lcurve_buf.createBuilder();
1469  for (int i = 0; i < mesh->GetNE(); i++)
1470  {
1471  mesh->GetElementVertices(i, vertices);
1472  mesh->GetPointMatrix(i, pointmat);
1473  sol->GetSubVector(vertices, values);
1474  if (logscale)
1475  for (int j = 0; j < vertices.Size(); j++)
1476  {
1477  values(j) = _LogVal(values(j));
1478  }
1479  RG.SetSize(vertices.Size());
1480  DrawLevelCurves(build, RG, pointmat, values, vertices.Size(), level);
1481  }
1482  updated_bufs.emplace_back(&lcurve_buf);
1483 }
1484 
1486  gl3::GlBuilder& builder, Array<int> &RG, DenseMatrix &pointmat, Vector &values,
1487  int sides, Array<double> &lvl, int flat)
1488 {
1489  double point[4][4];
1490  // double zc = 0.5*(z[0]+z[1]);
1491  double zc = bb.z[1];
1492 
1493  for (int k = 0; k < RG.Size()/sides; k++)
1494  {
1495  if (split_quads == 0 || sides == 3)
1496  {
1497  for (int j = 0; j < sides; j++)
1498  {
1499  int vv = RG[sides*k+j];
1500  point[j][0] = pointmat(0, vv);
1501  point[j][1] = pointmat(1, vv);
1502  point[j][3] = values(vv);
1503  point[j][2] = (flat) ? zc : point[j][3];
1504  }
1505  DrawPolygonLevelLines(builder, point[0], sides, lvl, logscale);
1506  }
1507  else if (split_quads == 1)
1508  {
1509  // split the quad into 2 triangles
1510  // (with the 0-2 diagonal)
1511  int *ind = &RG[sides*k];
1512  const int vt[2][3] = {{ 0, 1, 2 }, { 2, 3, 0 }};
1513  for (int it = 0; it < 2; it++)
1514  {
1515  for (int j = 0; j < 3; j++)
1516  {
1517  point[j][0] = pointmat(0, ind[vt[it][j]]);
1518  point[j][1] = pointmat(1, ind[vt[it][j]]);
1519  point[j][3] = values(ind[vt[it][j]]);
1520  point[j][2] = (flat) ? zc : point[j][3];
1521  }
1522  DrawPolygonLevelLines(builder, point[0], 3, lvl, logscale);
1523  }
1524  }
1525  else
1526  {
1527  // split the quad into 4 triangles
1528  // (with the two diagonals)
1529  int *ind = &RG[sides*k];
1530  point[2][0] = point[2][1] = point[2][2] = 0.0;
1531  for (int j = 0; j < 4; j++)
1532  {
1533  point[2][0] += pointmat(0, ind[j]);
1534  point[2][1] += pointmat(1, ind[j]);
1535  point[2][2] += values(ind[j]);
1536  }
1537  point[2][0] *= 0.25;
1538  point[2][1] *= 0.25;
1539  point[2][2] *= 0.25;
1540  point[2][3] = point[2][2];
1541  if (flat)
1542  {
1543  point[2][2] = zc;
1544  }
1545 
1546  for (int j = 0; j < 4; j++)
1547  {
1548  point[0][0] = pointmat(0, ind[j]);
1549  point[0][1] = pointmat(1, ind[j]);
1550  point[0][3] = values(ind[j]);
1551  point[0][2] = (flat) ? zc : point[0][3];
1552  int l = (j+1)%4;
1553  point[1][0] = pointmat(0, ind[l]);
1554  point[1][1] = pointmat(1, ind[l]);
1555  point[1][3] = values(ind[l]);
1556  point[1][2] = (flat) ? zc : point[1][3];
1557 
1558  DrawPolygonLevelLines(builder, point[0], 3, lvl, logscale);
1559  }
1560  }
1561  }
1562 }
1563 
1565 {
1566  int i, ne = mesh -> GetNE();
1567  Vector values;
1568  DenseMatrix pointmat;
1569  RefinedGeometry *RefG;
1570 
1571  lcurve_buf.clear();
1572  gl3::GlBuilder build = lcurve_buf.createBuilder();
1573  for (i = 0; i < ne; i++)
1574  {
1575  RefG = GLVisGeometryRefiner.Refine(mesh->GetElementBaseGeometry(i),
1576  TimesToRefine, EdgeRefineFactor);
1577  GetRefinedValues (i, RefG->RefPts, values, pointmat);
1578  Array<int> &RG = RefG->RefGeoms;
1579  int sides = mesh->GetElement(i)->GetNVertices();
1580 
1581  DrawLevelCurves(build, RG, pointmat, values, sides, level);
1582  }
1583  updated_bufs.emplace_back(&lcurve_buf);
1584 }
1585 
1587 {
1588  if (shading == 2)
1589  {
1590  // PrepareLines2();
1591  PrepareLines3();
1592  return;
1593  }
1594 
1595  int i, j, ne = mesh -> GetNE();
1596  DenseMatrix pointmat;
1597  Array<int> vertices;
1598 
1599  line_buf.clear();
1600  gl3::GlBuilder lb = line_buf.createBuilder();
1601 
1602  for (i = 0; i < ne; i++)
1603  {
1604  if (!el_attr_to_show[mesh->GetAttribute(i)-1]) { continue; }
1605 
1606  lb.glBegin(GL_LINE_LOOP);
1607  mesh->GetPointMatrix (i, pointmat);
1608  mesh->GetElementVertices (i, vertices);
1609 
1610  for (j = 0; j < pointmat.Size(); j++)
1611  lb.glVertex3d(pointmat(0, j), pointmat(1, j),
1612  LogVal((*sol)(vertices[j])));
1613  lb.glEnd();
1614  }
1615 
1616  updated_bufs.emplace_back(&line_buf);
1617 }
1618 
1620 {
1621  DenseMatrix pointmat;
1622  Array<int> vertices;
1623 
1624  mesh->GetPointMatrix(k, pointmat);
1625  mesh->GetElementVertices(k, vertices);
1626 
1627  // Get length scale for x mark
1628  double xmax = -numeric_limits<double>::infinity();
1629  double ymax = -numeric_limits<double>::infinity();
1630  double xmin = numeric_limits<double>::infinity();
1631  double ymin = numeric_limits<double>::infinity();
1632 
1633  int nv = vertices.Size();
1634  for (int j = 0; j < nv; j++)
1635  {
1636  double x = pointmat(0,j);
1637  double y = pointmat(1,j);
1638  if (x > xmax) { xmax = x; }
1639  if (x < xmin) { xmin = x; }
1640  if (y > ymax) { ymax = y; }
1641  if (y < ymin) { ymin = y; }
1642  }
1643  double dx = xmax-xmin;
1644  double dy = ymax-ymin;
1645  double ds = std::min<double>(dx,dy);
1646 
1647  return ds;
1648 }
1649 
1651 {
1652  if (2 == shading)
1653  {
1654  PrepareElementNumbering2();
1655  }
1656  else
1657  {
1658  PrepareElementNumbering1();
1659  }
1660 }
1661 
1663 {
1664  e_nums_buf.clear();
1665 
1666  DenseMatrix pointmat;
1667  Array<int> vertices;
1668 
1669  int ne = mesh->GetNE();
1670  for (int k = 0; k < ne; k++)
1671  {
1672  mesh->GetPointMatrix (k, pointmat);
1673  mesh->GetElementVertices (k, vertices);
1674  int nv = vertices.Size();
1675 
1676  ShrinkPoints(pointmat, k, 0, 0);
1677 
1678  double xs = 0.0;
1679  double ys = 0.0;
1680  double us = 0.0;
1681  for (int j = 0; j < nv; j++)
1682  {
1683  xs += pointmat(0,j);
1684  ys += pointmat(1,j);
1685  us += LogVal((*sol)(vertices[j]));
1686  }
1687  xs /= nv;
1688  ys /= nv;
1689  us /= nv;
1690 
1691  double ds = GetElementLengthScale(k);
1692  double dx = 0.05*ds;
1693 
1694  double xx[3] = {xs,ys,us};
1695  DrawNumberedMarker(e_nums_buf,xx,dx,k);
1696  }
1697 
1698  updated_bufs.emplace_back(&e_nums_buf);
1699 }
1700 
1702 {
1703  IntegrationRule center_ir(1);
1704  DenseMatrix pointmat;
1705  Vector values;
1706 
1707  e_nums_buf.clear();
1708 
1709  int ne = mesh->GetNE();
1710  for (int i = 0; i < ne; i++)
1711  {
1712  if (!el_attr_to_show[mesh->GetAttribute(i)-1]) { continue; }
1713 
1714  center_ir.IntPoint(0) =
1715  Geometries.GetCenter(mesh->GetElementBaseGeometry(i));
1716  GetRefinedValues (i, center_ir, values, pointmat);
1717 
1718  double xc = pointmat(0,0);
1719  double yc = pointmat(1,0);
1720  double uc = values(0);
1721 
1722  double ds = GetElementLengthScale(i);
1723  double dx = 0.05*ds;
1724 
1725  double xx[3] = {xc,yc,uc};
1726  DrawNumberedMarker(e_nums_buf,xx,dx,i);
1727  }
1728 
1729  updated_bufs.emplace_back(&e_nums_buf);
1730 }
1731 
1733 {
1734  if (2 == shading)
1735  {
1736  PrepareVertexNumbering2();
1737  }
1738  else
1739  {
1740  PrepareVertexNumbering1();
1741  }
1742 }
1743 
1745 {
1746  v_nums_buf.clear();
1747 
1748  DenseMatrix pointmat;
1749  Array<int> vertices;
1750 
1751  // Draw the vertices for each element. This is redundant, except
1752  // when the elements or domains are shrunk.
1753 
1754  const int ne = mesh->GetNE();
1755  for (int k = 0; k < ne; k++)
1756  {
1757  mesh->GetPointMatrix (k, pointmat);
1758  mesh->GetElementVertices (k, vertices);
1759  int nv = vertices.Size();
1760 
1761  ShrinkPoints(pointmat, k, 0, 0);
1762 
1763  double ds = GetElementLengthScale(k);
1764  double xs = 0.05*ds;
1765 
1766  for (int j = 0; j < nv; j++)
1767  {
1768  double x = pointmat(0,j);
1769  double y = pointmat(1,j);
1770  double u = LogVal((*sol)(vertices[j]));
1771 
1772  double xx[3] = {x,y,u};
1773  DrawNumberedMarker(v_nums_buf,xx,xs,vertices[j]);
1774  }
1775  }
1776 
1777  updated_bufs.emplace_back(&v_nums_buf);
1778 }
1779 
1781 {
1782  DenseMatrix pointmat;
1783  Vector values;
1784  Array<int> vertices;
1785 
1786  v_nums_buf.clear();
1787 
1788  const int ne = mesh->GetNE();
1789  for (int i = 0; i < ne; i++)
1790  {
1791  if (!el_attr_to_show[mesh->GetAttribute(i)-1]) { continue; }
1792 
1793  mesh->GetElementVertices (i, vertices);
1794 
1795  const IntegrationRule &vert_ir =
1796  *Geometries.GetVertices(mesh->GetElementBaseGeometry(i));
1797 
1798  GetRefinedValues (i, vert_ir, values, pointmat);
1799 
1800  double ds = GetElementLengthScale(i);
1801  double xs = 0.05*ds;
1802 
1803  for (int j = 0; j < values.Size(); j++)
1804  {
1805  double xv = pointmat(0, j);
1806  double yv = pointmat(1, j);
1807 
1808  double u = values[j];
1809 
1810  double xx[3] = {xv,yv,u};
1811  DrawNumberedMarker(v_nums_buf,xx,xs,vertices[j]);
1812  }
1813  }
1814 
1815  updated_bufs.emplace_back(&v_nums_buf);
1816 }
1817 
1819 {
1820  f_nums_buf.clear();
1821 
1822  DenseMatrix p;
1823  Array<int> vertices;
1824  Array<int> edges;
1825  Array<int> edges_ori;
1826 
1827  const int ne = mesh->GetNE();
1828  for (int k = 0; k < ne; k++)
1829  {
1830  mesh->GetElementEdges(k, edges, edges_ori);
1831 
1832  double ds = GetElementLengthScale(k);
1833  double xs = 0.05 * ds;
1834 
1835  for (int i = 0; i < edges.Size(); i++)
1836  {
1837  mesh->GetEdgeVertices(edges[i], vertices);
1838 
1839  p.SetSize(mesh->Dimension(), vertices.Size());
1840  p.SetCol(0, mesh->GetVertex(vertices[0]));
1841  p.SetCol(1, mesh->GetVertex(vertices[1]));
1842 
1843  ShrinkPoints(p, k, 0, 0);
1844 
1845  const double m[2] = {0.5 * (p(0,0) + p(0,1)), 0.5 * (p(1,0) + p(1,1))};
1846  // TODO: figure out something better...
1847  double u = LogVal(0.5 * ((*sol)(vertices[0]) + (*sol)(vertices[1])));
1848 
1849  double xx[3] = {m[0], m[1], u};
1850  DrawNumberedMarker(f_nums_buf, xx, xs, edges[i]);
1851  }
1852  }
1853 
1854  updated_bufs.emplace_back(&f_nums_buf);
1855 }
1856 
1858 {
1859  bool color = draworder < 3;
1860  order_buf.clear();
1861  order_noarrow_buf.clear();
1862  PrepareOrderingCurve1(order_buf, true, color);
1863  PrepareOrderingCurve1(order_noarrow_buf, false, color);
1864  updated_bufs.emplace_back(&order_buf);
1865  updated_bufs.emplace_back(&order_noarrow_buf);
1866 }
1867 
1869  bool arrows,
1870  bool color)
1871 {
1872  gl3::GlBuilder builder = buf.createBuilder();
1873  DenseMatrix pointmat;
1874  Array<int> vertices;
1875 
1876  DenseMatrix pointmat1;
1877  Array<int> vertices1;
1878 
1879  int ne = mesh->GetNE();
1880  for (int k = 0; k < ne-1; k++)
1881  {
1882  mesh->GetPointMatrix (k, pointmat);
1883  mesh->GetElementVertices (k, vertices);
1884  mesh->GetPointMatrix (k+1, pointmat1);
1885  mesh->GetElementVertices (k+1, vertices1);
1886  int nv = vertices.Size();
1887  int nv1 = vertices1.Size();
1888 
1889  ShrinkPoints(pointmat, k, 0, 0);
1890  ShrinkPoints(pointmat1, k+1, 0, 0);
1891 
1892  double xs = 0.0;
1893  double ys = 0.0;
1894  double us = 0.0;
1895  for (int j = 0; j < nv; j++)
1896  {
1897  xs += pointmat(0,j);
1898  ys += pointmat(1,j);
1899  us += maxv + double(k)/ne*(maxv-minv);
1900  }
1901  xs /= nv;
1902  ys /= nv;
1903  us /= nv;
1904 
1905  double xs1 = 0.0;
1906  double ys1 = 0.0;
1907  double us1 = 0.0;
1908  for (int j = 0; j < nv1; j++)
1909  {
1910  xs1 += pointmat1(0,j);
1911  ys1 += pointmat1(1,j);
1912  us1 += maxv + double(k+1)/ne*(maxv-minv);
1913  }
1914  xs1 /= nv1;
1915  ys1 /= nv1;
1916  us1 /= nv1;
1917 
1918  double dx = xs1-xs;
1919  double dy = ys1-ys;
1920  double du = us1-us;
1921  double ds = sqrt(dx*dx+dy*dy+du*du);
1922 
1923  if (color)
1924  {
1925  double cval = minv+double(k)/ne*(maxv-minv);
1926  MySetColor(builder, cval, minv, maxv);
1927  }
1928 
1929  if (arrows)
1930  {
1931  Arrow3(builder,
1932  xs,ys,us,
1933  dx,dy,du,
1934  ds,0.05);
1935  }
1936  else
1937  {
1938  Arrow3(builder,
1939  xs,ys,us,
1940  dx,dy,du,
1941  ds,0.0);
1942  }
1943  }
1944 }
1945 
1947 {
1948  PrepareElementNumbering();
1949  PrepareEdgeNumbering();
1950  PrepareVertexNumbering();
1951 }
1952 
1954 {
1955  int i, j, k, ne = mesh -> GetNE();
1956  Vector values;
1957  DenseMatrix pointmat;
1958  RefinedGeometry *RefG;
1959 
1960  line_buf.clear();
1961  gl3::GlBuilder lb = line_buf.createBuilder();
1962 
1963  for (i = 0; i < ne; i++)
1964  {
1965  if (!el_attr_to_show[mesh->GetAttribute(i)-1]) { continue; }
1966 
1967  RefG = GLVisGeometryRefiner.Refine(mesh->GetElementBaseGeometry(i),
1968  TimesToRefine, EdgeRefineFactor);
1969  GetRefinedValues (i, RefG->RefPts, values, pointmat);
1970  Array<int> &RG = RefG->RefGeoms;
1971  int sides = mesh->GetElement(i)->GetNVertices();
1972 
1973  for (k = 0; k < RG.Size()/sides; k++)
1974  {
1975  lb.glBegin(GL_LINE_LOOP);
1976 
1977  for (j = 0; j < sides; j++)
1978  lb.glVertex3d(pointmat(0, RG[sides*k+j]),
1979  pointmat(1, RG[sides*k+j]),
1980  values(RG[sides*k+j]));
1981  lb.glEnd();
1982  }
1983  }
1984 
1985  updated_bufs.emplace_back(&line_buf);
1986 }
1987 
1989 {
1990  int i, k, ne = mesh -> GetNE();
1991  Vector values;
1992  DenseMatrix pointmat;
1993  RefinedGeometry *RefG;
1994 
1995  line_buf.clear();
1996  gl3::GlBuilder lb = line_buf.createBuilder();
1997 
1998  for (i = 0; i < ne; i++)
1999  {
2000  if (!el_attr_to_show[mesh->GetAttribute(i)-1]) { continue; }
2001  RefG = GLVisGeometryRefiner.Refine(mesh->GetElementBaseGeometry(i),
2002  TimesToRefine, EdgeRefineFactor);
2003  GetRefinedValues (i, RefG->RefPts, values, pointmat);
2004  Array<int> &RE = RefG->RefEdges;
2005 
2006  lb.glBegin (GL_LINES);
2007  for (k = 0; k < RE.Size()/2; k++)
2008  {
2009  lb.glVertex3d (pointmat(0, RE[2*k]),
2010  pointmat(1, RE[2*k]),
2011  values(RE[2*k]));
2012  lb.glVertex3d (pointmat(0, RE[2*k+1]),
2013  pointmat(1, RE[2*k+1]),
2014  values(RE[2*k+1]));
2015  }
2016  lb.glEnd();
2017  }
2018 
2019  updated_bufs.emplace_back(&line_buf);
2020 }
2021 
2023 {
2024  bool had_logscale = logscale;
2025  logscale = logscale && LogscaleRange();
2026  SetLogA();
2027  SetLevelLines(minv, maxv, nl);
2028  // preserve the current box z-size
2029  zscale *= (bb.z[1]-bb.z[0])/(maxv-minv);
2030  bb.z[0] = minv;
2031  bb.z[1] = maxv;
2032  PrepareAxes();
2033  if (prepare)
2034  {
2035  UpdateLevelLines();
2036  EventUpdateColors();
2037  if (had_logscale)
2038  {
2039  PrepareLines();
2040  PrepareBoundary();
2041  PrepareCP();
2042  }
2043  }
2044 }
2045 
2047 {
2048  int i, j, ne = mesh->GetNBE();
2049  Array<int> vertices;
2050  DenseMatrix pointmat;
2051 
2052  bdr_buf.clear();
2053  gl3::GlBuilder bl = bdr_buf.createBuilder();
2054  if (shading != 2)
2055  {
2056  bl.glBegin(GL_LINES);
2057  for (i = 0; i < ne; i++)
2058  {
2059  if (!bdr_el_attr_to_show[mesh->GetBdrAttribute(i)-1]) { continue; }
2060  mesh->GetBdrElementVertices(i, vertices);
2061  mesh->GetBdrPointMatrix(i, pointmat);
2062  for (j = 0; j < pointmat.Size(); j++)
2063  bl.glVertex3d(pointmat(0, j), pointmat(1, j),
2064  LogVal((*sol)(vertices[j])));
2065  }
2066  bl.glEnd();
2067  }
2068  else // shading == 2
2069  {
2070  int en;
2071  FaceElementTransformations *T;
2072  RefinedGeometry *RefG =
2073  GLVisGeometryRefiner.Refine(Geometry::SEGMENT, TimesToRefine,
2074  EdgeRefineFactor);
2075  IntegrationRule &ir = RefG->RefPts;
2076  IntegrationRule eir(ir.GetNPoints());
2077  Vector vals;
2078  double shr = shrink;
2079  shrink = 1.0;
2080 
2081  for (i = 0; i < ne; i++)
2082  {
2083  if (!bdr_el_attr_to_show[mesh->GetBdrAttribute(i)-1]) { continue; }
2084  en = mesh->GetBdrElementEdgeIndex(i);
2085  T = mesh->GetFaceElementTransformations(en, 4);
2086  T->Loc1.Transform(ir, eir);
2087  GetRefinedValues(T->Elem1No, eir, vals, pointmat);
2088  bl.glBegin(GL_LINE_STRIP);
2089  if (drawbdr == 2)
2090  {
2091  const double val = mesh->GetBdrAttribute(i);
2092  MySetColor(bl, val, minv, maxv);
2093  for (j = 0; j < vals.Size(); j++)
2094  {
2095  bl.glVertex3d(pointmat(0, j), pointmat(1, j), val);
2096  }
2097  }
2098  else
2099  {
2100  for (j = 0; j < vals.Size(); j++)
2101  {
2102  bl.glVertex3d(pointmat(0, j), pointmat(1, j), vals(j));
2103  }
2104  }
2105  bl.glEnd();
2106 
2107  if (T->Elem2No >= 0)
2108  {
2109  T = mesh->GetFaceElementTransformations(en, 8);
2110  T->Loc2.Transform(ir, eir);
2111  GetRefinedValues(T->Elem2No, eir, vals, pointmat);
2112  bl.glBegin(GL_LINE_STRIP);
2113  for (j = 0; j < vals.Size(); j++)
2114  {
2115  bl.glVertex3d(pointmat(0, j), pointmat(1, j), vals(j));
2116  }
2117  bl.glEnd();
2118  }
2119  }
2120  shrink = shr;
2121  }
2122 
2123  updated_bufs.emplace_back(&bdr_buf);
2124 }
2125 
2127 {
2128  Vector values;
2129  DenseMatrix pointmat;
2130  Array<int> ind;
2131 
2132  if (draw_cp == 0)
2133  {
2134  return;
2135  }
2136 
2137  cp_buf.clear();
2138  gl3::GlBuilder bld = cp_buf.createBuilder();
2139  bld.glBegin(GL_LINES);
2140 
2141  if (shading != 2)
2142  {
2143  Array<int> vertices;
2144 
2145  for (int i = 0; i < mesh->GetNE(); i++)
2146  {
2147  mesh->GetPointMatrix(i, pointmat);
2148  int n = 0;
2149  for (int j = 0; j < pointmat.Width(); j++)
2150  {
2151  const double s =
2152  CuttingPlane->Transform(pointmat(0, j),
2153  pointmat(1, j), 0.0);
2154  if (s >= 0.0)
2155  {
2156  n++;
2157  }
2158  }
2159  if (n == 0 || n == pointmat.Width())
2160  {
2161  continue;
2162  }
2163 
2164  mesh->GetElementVertices(i, vertices);
2165  values.SetSize(vertices.Size());
2166  ind.SetSize(vertices.Size());
2167  for (int j = 0; j < values.Size(); j++)
2168  {
2169  values(j) = LogVal((*sol)(vertices[j]));
2170  ind[j] = j;
2171  }
2172 
2173  DrawCPLine(bld, pointmat, values, ind);
2174  }
2175  }
2176  else
2177  {
2178  RefinedGeometry *RefG;
2179 
2180  for (int i = 0; i < mesh->GetNE(); i++)
2181  {
2182  RefG = GLVisGeometryRefiner.Refine(mesh->GetElementBaseGeometry(i),
2183  TimesToRefine, EdgeRefineFactor);
2184  GetRefinedValues (i, RefG->RefPts, values, pointmat);
2185  Array<int> &RG = RefG->RefGeoms;
2186  int sides = mesh->GetElement(i)->GetNVertices();
2187 
2188  ind.SetSize(sides);
2189  for (int k = 0; k < RG.Size()/sides; k++)
2190  {
2191  for (int j = 0; j < sides; j++)
2192  {
2193  ind[j] = RG[k*sides+j];
2194  }
2195 
2196  int n = 0;
2197  for (int j = 0; j < sides; j++)
2198  {
2199  const double s =
2200  CuttingPlane->Transform(pointmat(0, ind[j]),
2201  pointmat(1, ind[j]), 0.0);
2202  if (s >= 0.0)
2203  {
2204  n++;
2205  }
2206  }
2207  if (n == 0 || n == sides)
2208  {
2209  continue;
2210  }
2211 
2212  DrawCPLine(bld, pointmat, values, ind);
2213  }
2214  }
2215  }
2216 
2217  bld.glEnd();
2218  updated_bufs.emplace_back(&cp_buf);
2219 }
2220 
2222  gl3::GlBuilder& bld, DenseMatrix &pointmat, Vector &values, Array<int> &ind)
2223 {
2224  int n, js, nv = ind.Size();
2225  double s, xs, ys;
2226 
2227  js = nv-1;
2228  xs = pointmat(0, ind[js]);
2229  ys = pointmat(1, ind[js]);
2230  s = CuttingPlane->Transform(xs, ys, 0.0);
2231  n = 0;
2232  for (int j = 0; j < nv; j++)
2233  {
2234  const double xt = pointmat(0, ind[j]);
2235  const double yt = pointmat(1, ind[j]);
2236  const double t = CuttingPlane->Transform(xt, yt, 0.0);
2237  if ((s >= 0.0 && t < 0.0) || (s < 0.0 && t >= 0.0))
2238  {
2239  double a = fabs(s) / (fabs(s) + fabs(t));
2240 
2241  bld.glVertex3d((1.-a) * xs + a * xt,
2242  (1.-a) * ys + a * yt,
2243  (1.-a) * values(ind[js]) + a * values(ind[j]));
2244  n++;
2245  }
2246  s = t;
2247  js = j;
2248  xs = xt;
2249  ys = yt;
2250  }
2251  if (n != 2 && n != 4)
2252  {
2253  cerr << "n = " << n << endl;
2254  mfem_error("VisualizationSceneSolution::DrawCPLine");
2255  }
2256 }
2257 
2259 {
2260  if (colorbar)
2261  {
2262  // update color bar before we get the base class scene
2263  PrepareColorBar(minv, maxv, (drawmesh == 2) ? &level : nullptr );
2264  }
2266  gl3::RenderParams params = GetMeshDrawParams();
2267  params.use_clip_plane = draw_cp;
2268  double* cp_eqn = CuttingPlane->Equation();
2269  params.clip_plane_eqn = {cp_eqn[0], cp_eqn[1], cp_eqn[2], cp_eqn[3]};
2270  params.contains_translucent = matAlpha < 1.0;
2271  if (drawelems)
2272  {
2273  // draw elements
2274  scene.queue.emplace_back(params, &disp_buf);
2275  }
2276  // draw orderings -- color modes
2277  params.contains_translucent = false;
2278  if (draworder == 1)
2279  {
2280  scene.queue.emplace_back(params, &order_noarrow_buf);
2281  }
2282  else if (draworder == 2)
2283  {
2284  scene.queue.emplace_back(params, &order_buf);
2285  }
2286  params.contains_translucent = matAlpha < 1.0;
2288  // everything below will be drawn in "black"
2289  params.static_color = GetLineColor();
2290  if (draw_cp)
2291  {
2292  // draw cutting plane
2293  params.use_clip_plane = false;
2294  scene.queue.emplace_back(params, &cp_buf);
2295  params.use_clip_plane = true;
2296  }
2297  // disable lighting for objects below
2298  params.num_pt_lights = 0;
2299 
2300  // draw boundary in 2D
2301  if (drawbdr)
2302  {
2303  scene.queue.emplace_back(params, &bdr_buf);
2304  }
2305 
2306  // draw lines
2307  if (drawmesh == 1)
2308  {
2309  scene.queue.emplace_back(params, &line_buf);
2310  }
2311  else if (drawmesh == 2)
2312  {
2313  scene.queue.emplace_back(params, &lcurve_buf);
2314  }
2315 
2316  // draw numberings
2317  if (drawnums == 1)
2318  {
2319  scene.queue.emplace_back(params, &e_nums_buf);
2320  }
2321  else if (drawnums == 2)
2322  {
2323  scene.queue.emplace_back(params, &f_nums_buf);
2324  }
2325  else if (drawnums == 3)
2326  {
2327  scene.queue.emplace_back(params, &v_nums_buf);
2328  }
2329 
2330  // draw orderings -- "black" modes
2331  if (draworder == 3)
2332  {
2333  scene.queue.emplace_back(params, &order_noarrow_buf);
2334  }
2335  else if (draworder == 4)
2336  {
2337  scene.queue.emplace_back(params, &order_buf);
2338  }
2339 
2340  return scene;
2341 }
2342 
2344  glTF_Builder &bld,
2345  glTF_Builder::buffer_id buffer,
2346  glTF_Builder::material_id black_mat)
2347 {
2348  auto bdr_node = AddModelNode(bld, "Boundary");
2349  auto bdr_mesh = bld.addMesh("Boundary Mesh");
2350  bld.addNodeMesh(bdr_node, bdr_mesh);
2351 
2352  int nlines = AddLines(
2353  bld,
2354  bdr_mesh,
2355  buffer,
2356  black_mat,
2357  bdr_buf);
2358  if (nlines == 0)
2359  {
2360  cout << "glTF export: no boundary found to export!" << endl;
2361  }
2362 }
2363 
2365 {
2366  string name = "GLVis_scene_000";
2367 
2368  glTF_Builder bld(name);
2369 
2370  auto palette_mat = AddPaletteMaterial(bld);
2371  auto black_mat = AddBlackMaterial(bld);
2372  auto buf = bld.addBuffer("buffer");
2373  if (drawelems) { glTF_ExportElements(bld, buf, palette_mat, disp_buf); }
2374  if (drawmesh)
2375  {
2376  glTF_ExportMesh(bld, buf, black_mat,
2377  (drawmesh == 1) ? line_buf : lcurve_buf);
2378  }
2379  if (drawbdr) { glTF_ExportBoundary(bld, buf, black_mat); }
2380  if (drawaxes) { glTF_ExportBox(bld, buf, black_mat); }
2381  bld.writeFile();
2382 
2383  cout << "Exported glTF -> " << name << ".gltf" << endl;
2384 }
void SendExposeEvent()
Send expose event. In our case MyReshape is executed and Draw after it.
Definition: aux_vis.cpp:346
thread_local GeometryRefiner GLVisGeometryRefiner
Definition: glvis.cpp:71
virtual void ToggleDrawElems()
Definition: vssolution.cpp:523
void GetRefinedDetJ(int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr)
Definition: vssolution.cpp:607
Array< int > el_attr_to_show
Definition: vssolution.hpp:86
void glVertex3d(double x, double y, double z)
Definition: types.hpp:332
thread_local SdlWindow * wnd
Definition: aux_vis.cpp:50
virtual std::string GetHelpString() const
Definition: vssolution.cpp:51
double GetElementLengthScale(int k)
virtual void SetShading(int, bool)
Definition: vssolution.cpp:743
void glTF_ExportBoundary(glTF_Builder &bld, glTF_Builder::buffer_id buffer, glTF_Builder::material_id black_mat)
void glEnd()
Definition: types.hpp:309
Array< int > bdr_el_attr_to_show
Definition: vssolution.hpp:86
virtual gl3::SceneInfo GetSceneObjs()
Definition: vsdata.cpp:984
void RemoveFPErrors(const DenseMatrix &pts, Vector &vals, DenseMatrix &normals, const int n, const Array< int > &ind, Array< int > &f_ind)
void DrawNumberedMarker(gl3::GlDrawable &buff, const double x[3], double dx, int n)
virtual void ToggleLogscale(bool print)
void PrepareOrderingCurve1(gl3::GlDrawable &buf, bool arrows, bool color)
virtual void EventUpdateBackground()
const int split_quads
void glNormal3dv(const double *d)
Definition: types.hpp:407
virtual void SetRefineFactors(int, int)
Definition: vssolution.cpp:876
Definition: vsdata.hpp:25
buffer_id addBuffer(const std::string &bufferName)
Definition: gltf.cpp:24
int isfinite(double x)
Definition: vssolution.cpp:36
void KeyNPressed()
Definition: vsvector.cpp:116
void glBegin(GLenum e)
Definition: types.hpp:295
void FindNewBox(double rx[], double ry[], double rval[])
Definition: vssolution.cpp:969
int Compute3DUnitNormal(const double p1[], const double p2[], const double p3[], double nor[])
Definition: geom_utils.hpp:101
void addText(float x, float y, float z, const std::string &text)
Adds a string at the given position in object coordinates.
Definition: types.hpp:658
virtual ~VisualizationSceneSolution()
Definition: vssolution.cpp:519
virtual void GetRefinedValues(int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr)
Definition: vssolution.cpp:660
double shrinkmat
Shrink factor with respect to the element (material) attributes centers.
Definition: vsdata.hpp:136
void glNormal3d(double nx, double ny, double nz)
Definition: types.hpp:401
virtual void EventUpdateColors()
void DecreaseTheta()
Definition: vsdata.cpp:1729
void NewMeshAndSolution(Mesh *new_m, Vector *new_sol, GridFunction *new_u=NULL)
Definition: vssolution.cpp:575
GlBuilder createBuilder()
Definition: types.hpp:731
void DrawCPLine(gl3::GlBuilder &bld, DenseMatrix &pointmat, Vector &values, Array< int > &ind)
thread_local VisualizationSceneSolution * vssol
Definition: vssolution.cpp:28
mesh_id addMesh(const std::string &meshName)
Definition: gltf.cpp:322
virtual void UpdateValueRange(bool prepare)
virtual void FindMeshBox(bool prepare)
Crude fixed-function OpenGL emulation helper.
Definition: types.hpp:261
void DrawLevelCurves(gl3::GlBuilder &buf, Array< int > &RG, DenseMatrix &pointmat, Vector &values, int sides, Array< double > &lvl, int flat=0)
int writeFile()
Definition: gltf.cpp:472
void KeyiPressed()
Definition: vssolution.cpp:317
thread_local string extra_caption
Definition: glvis.cpp:61
void addNodeMesh(node_id node, mesh_id mesh)
Definition: gltf.cpp:433
void DecreaseDistance()
Definition: vsdata.cpp:1745
void KeyIPressed()
Definition: vssolution.cpp:323
virtual void FindNewValueRange(bool prepare)
void IncreaseDistance()
Definition: vsdata.cpp:1735
bool contains_translucent
Definition: renderer.hpp:55
virtual void SetNewScalingFromBox()
Definition: vsdata.cpp:1269
std::array< float, 4 > static_color
Definition: renderer.hpp:48
void setOnKeyDown(int key, Delegate func)
Definition: sdl.hpp:188
RenderQueue queue
Definition: renderer.hpp:63
virtual void SetNewScalingFromBox()
Definition: vssolution.cpp:950
void ComputeElemAttrCenter()
Compute the center of gravity for each element attribute.
Definition: vsdata.cpp:1641
void IncreaseTheta()
Definition: vsdata.cpp:1723
Material mesh_material
Definition: renderer.hpp:44
std::array< double, 4 > clip_plane_eqn
Definition: renderer.hpp:52
thread_local VisualizationScene * locscene
Definition: aux_vis.cpp:38
virtual int GetRefinedValuesAndNormals(int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr, DenseMatrix &normals)
Definition: vssolution.cpp:684
void KeyBPressed()
Definition: vsvector.cpp:122
virtual gl3::SceneInfo GetSceneObjs()
virtual void ToggleAttributes(Array< int > &attr_list)
Definition: vssolution.cpp:924
const Material BLK_MAT
Definition: openglvis.hpp:78