Thanks to visit codestin.com
Credit goes to glvis.github.io

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