GLVis  v4.2
Accurate and flexible finite element visualization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
vsvector.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 <limits>
15 #include <cmath>
16 
17 #include "mfem.hpp"
18 #include "visual.hpp"
19 
20 using namespace mfem;
21 using namespace std;
22 
24 {
25  std::stringstream os;
26  os << endl
27  << "+------------------------------------+" << endl
28  << "| Keys |" << endl
29  << "+------------------------------------+" << endl
30  << "| a - Displays/Hides the axes |" << endl
31  << "| A - Turns antialiasing on/off |" << endl
32  << "| b - Displacements step back |" << endl
33  << "| B - Toggle 2D boundary |" << endl
34  << "| c - Toggle colorbar and caption |" << endl
35  << "| C - Change the main plot caption |" << endl
36  << "| d - Displays/Hides displacements |" << endl
37  << "| e - Displays/Hides the elements |" << endl
38  << "| f - Smooth/Flat shading |" << endl
39  << "| g - Toggle background |" << endl
40  << "| h - Displays help menu |" << endl
41  << "| i - Toggle the cutting plane |" << endl
42  << "| j - Turn on/off perspective |" << endl
43  << "| k/K Adjust the transparency level |" << endl
44  << "| ,/< Adjust color transparency |" << endl
45  << "| l - Turns on/off the light |" << endl
46  << "| L - Toggle logarithmic scale |" << endl
47  << "| m - Displays/Hides the mesh |" << endl
48  << "| n - Displacements step forward |" << endl
49  << "| N - Cycle through numberings |" << endl
50  << "| o - (De)refine elem. (NC shading) |" << endl
51  << "| O - Switch 'o' func. (NC shading) |" << endl
52  << "| p/P Cycle through color palettes |" << endl
53  << "| q - Quits |" << endl
54  << "| r - Reset the plot to 3D view |" << endl
55  << "| R - Reset the plot to 2D view |" << endl
56  << "| s - Turn on/off unit cube scaling |" << endl
57  << "| S - Take snapshot/Record a movie |" << endl
58  << "| t - Cycle materials and lights |" << endl
59  << "| u - Vector sampling; scalar func. |" << endl
60  << "| U - Switch 'u' functionality |" << endl
61  << "| v - Cycle through vector fields |" << endl
62  << "| V - Change the arrows scaling |" << endl
63  << "| \\ - Set light source position |" << endl
64  << "| Ctrl+p - Print to a PDF file |" << endl
65  << "+------------------------------------+" << endl
66  << "| Function keys |" << endl
67  << "+------------------------------------+" << endl
68  << "| F1 - X window info and keystrokes |" << endl
69  << "| F2 - Update colors, etc. |" << endl
70  << "| F3/F4 - Shrink/Zoom elements |" << endl
71  << "| F5 - Set level lines |" << endl
72  << "| F6 - Palette options |" << endl
73  << "| F7 - Manually set min/max value |" << endl
74  << "| F8 - List of subdomains to show |" << endl
75  << "| F9/F10 - Walk through subdomains |" << endl
76  << "| F11/F12 - Shrink/Zoom subdomains |" << endl
77  << "+------------------------------------+" << endl
78  << "| Keypad |" << endl
79  << "+------------------------------------+" << endl
80  << "| 1-9 Small rotation, reset with 5 |" << endl
81  << "| *,/ Scale up/down |" << endl
82  << "| +/- Change z-scaling |" << endl
83  << "| . - Start/stop spinning |" << endl
84  << "| 0/Enter - Spinning speed and dir. |" << endl
85  << "+------------------------------------+" << endl
86  << "| Mouse |" << endl
87  << "+------------------------------------+" << endl
88  << "| left btn - Rotation |" << endl
89  << "| middle btn - Translation |" << endl
90  << "| right btn - Scaling |" << endl
91  << "| left + Alt - Tilt |" << endl
92  << "| left + Shift - Spinning |" << endl
93  << "| right + Shift - Change light pos. |" << endl
94  << "| left + Ctrl - Spherical rotation |" << endl
95  << "| middle+ Ctrl - Object translation |" << endl
96  << "| right + Ctrl - Object scaling |" << endl
97  << "| left + Ctrl + Shift - z-Spinning |" << endl
98  << "+------------------------------------+" << endl;
99  return os.str();
100 }
101 
103 extern thread_local VisualizationScene * locscene;
104 extern thread_local VisualizationSceneSolution * vssol;
105 extern thread_local GeometryRefiner GLVisGeometryRefiner;
106 
107 thread_local int ianim = 0;
108 thread_local int ianimmax = 10;
109 
111 {
112  vsvector -> ToggleDisplacements();
113  SendExposeEvent();
114 }
115 
117 {
118  ianim = (ianim + 1) % (ianimmax + 1);
119  vsvector -> NPressed();
120 }
121 
123 {
124  ianim = (ianim + ianimmax) % (ianimmax + 1);
125  vsvector -> NPressed();
126 }
127 
129 {
130  if (drawdisp == 0)
131  {
132  drawdisp = 1;
133  ianim = 0;
134  }
135 
136  PrepareDisplacedMesh();
137 
138  SendExposeEvent();
139 }
140 
142 {
143  vsvector -> ToggleVectorField();
144  SendExposeEvent();
145 }
146 
148 {
149  cout << "New arrow scale: " << flush;
150  cin >> vsvector -> ArrowScale;
151  cout << "New arrow scale = " << vsvector -> ArrowScale << endl;
152  vsvector -> PrepareVectorField();
153  SendExposeEvent();
154 }
155 
156 int key_u_func = 0;
157 
159 {
160  int update = 1;
161 
162  switch (key_u_func)
163  {
164  case 0:
166  break;
167 
168  case 1:
169  if (vsvector->RefineFactor > 1)
170  {
172  }
173  else
174  {
175  update = 0;
176  }
177  break;
178 
179  case 2:
181  SendExposeEvent();
182  break;
183  }
184 
185  switch (key_u_func)
186  {
187  case 0:
188  case 1:
189  if (update && vsvector->shading == 2)
190  {
192  SendExposeEvent();
193  }
194  cout << "Vector subdivision factor = "
195  << vsvector->RefineFactor << endl;
196  break;
197 
198  case 2:
199  break;
200  }
201 }
202 
204 {
205  key_u_func = (key_u_func+1)%3;
206  cout << "Key 'u' will: ";
207  switch (key_u_func)
208  {
209  case 0:
210  cout << "Increase vector subdivision factor" << endl;
211  break;
212 
213  case 1:
214  cout << "Decrease vector subdivision factor" << endl;
215  break;
216 
217  case 2:
218  cout << "Cycle through vector-to-scalar functions" << endl;
219  break;
220  }
221 }
222 
224 {
225  const char *modes[] =
226  { "none", "vector->scalar function", "det(J0)/det(J)", "det(J)/det(J0)" };
227 
228  drawelems = (drawelems+3)%4;
229 
230  cout << "Surface elements mode : " << modes[drawelems] << endl;
231 
232  if (drawelems != 0 && shading == 2)
233  {
234  DoAutoscaleValue(false);
235  PrepareLines();
236  PrepareBoundary();
237  Prepare();
238  PrepareLevelCurves();
239  PrepareCP();
240  }
241 }
242 
244 {
245  drawvector = (drawvector+1)%4;
246  PrepareVectorField();
247 }
248 
249 const char *Vec2ScalarNames[7] =
250 {
251  "magnitude", "direction", "x-component", "y-component", "divergence",
252  "curl", "anisotropy"
253 };
254 
256  Vector & sx, Vector & sy)
257 {
258  mesh = &m;
259  solx = &sx;
260  soly = &sy;
261 
262  sol = new Vector(mesh -> GetNV());
263 
264  VecGridF = NULL;
265 
266  Init();
267 }
268 
270 {
271  FiniteElementSpace *fes = vgf.FESpace();
272  if (fes == NULL || vgf.VectorDim() != 2)
273  {
274  cout << "VisualizationSceneVector::VisualizationSceneVector" << endl;
275  exit(1);
276  }
277 
278  VecGridF = &vgf;
279 
280  mesh = fes->GetMesh();
281 
282  solx = new Vector(mesh -> GetNV());
283  soly = new Vector(mesh -> GetNV());
284 
285  vgf.GetNodalValues (*solx, 1);
286  vgf.GetNodalValues (*soly, 2);
287 
288  sol = new Vector(mesh -> GetNV());
289 
290  // VisualizationSceneSolution::Init() sets rsol = NULL !
291  {
292  Init();
293  SetGridFunction(vgf);
294  }
295 
296  mesh->GetNodes(vc0);
297  if (vc0.Size() != vgf.Size())
298  {
299  vc0.Destroy();
300  }
301  else
302  {
303  vc0 += vgf;
304  }
305 }
306 
307 double VecLength(double x, double y)
308 {
309  return sqrt(x*x+y*y);
310 }
311 
312 double VecDirection(double x, double y)
313 {
314  return atan2(y, x);
315 }
316 
317 double VecDotNx(double x, double y)
318 {
319  return x;
320 }
321 
322 double VecDotNy(double x, double y)
323 {
324  return y;
325 }
326 
327 double VecDivSubst(double x, double y)
328 {
329  return 0.0;
330 }
331 
332 double VecCurlSubst(double x, double y)
333 {
334  return 0.0;
335 }
336 
337 double VecAnisotrSubst(double x, double y)
338 {
339  return 0.0;
340 }
341 
342 double (*Vec2ScalarFunctions[7])(double, double) =
343 {
346 };
347 
349 {
350  int i;
351 
352  for (i = 0; Vec2Scalar != Vec2ScalarFunctions[i]; i++)
353  ;
354 
355  if (VecGridF->FESpace()->GetVDim() == 1)
356  {
357  if (dynamic_cast<const ND_FECollection*>(VecGridF->FESpace()->FEColl()))
358  {
359  if (i == 5) { i = 0; }
360  else if (i == 3) { i = 5; }
361  else { i = (i + 1) % 5; }
362  }
363  else
364  {
365  i = (i + 1) % 5;
366  }
367  }
368  else
369  {
370  i = (i + 1) % 7;
371  }
372 
373  if (print)
374  {
375  cout << "Vector-to-scalar function: " << Vec2ScalarNames[i] << endl;
376  }
377 
378  Vec2Scalar = Vec2ScalarFunctions[i];
380 
381  for (i = 0; i < mesh->GetNV(); i++)
382  {
383  (*sol)(i) = Vec2Scalar((*solx)(i), (*soly)(i));
384  }
385 
386  // update scalar stuff
387  DoAutoscaleValue(false);
388  PrepareLines();
389  PrepareBoundary();
390  PrepareLevelCurves();
391  PrepareCP();
392  Prepare();
393 
394  if (i == 0)
395  {
396  maxlen = maxv;
397  }
398 
399  // update the colors of the vectors
400  if (drawvector > 1)
401  {
402  PrepareVectorField();
403  }
404 }
405 
407 {
408  delete sol;
409 
410  if (VecGridF)
411  {
412  delete soly;
413  delete solx;
414  }
415 
416  VecGridF = &vgf;
417 
418  // If the number of elements changes, recompute the refinement factor
419  Mesh *new_mesh = vgf.FESpace()->GetMesh();
420  if (mesh->GetNE() != new_mesh->GetNE())
421  {
422  mesh = new_mesh;
423  int ref = GetAutoRefineFactor();
424  if (TimesToRefine != ref || EdgeRefineFactor != 1)
425  {
426  TimesToRefine = ref;
427  EdgeRefineFactor = 1;
428  cout << "Subdivision factors = " << TimesToRefine << ", 1" << endl;
429  }
430  if (RefineFactor != 1)
431  {
432  RefineFactor = 1;
433  cout << "Vector subdivision factor = 1" << endl;
434  }
435  }
436  mesh = new_mesh;
437 
438  solx = new Vector(mesh->GetNV());
439  soly = new Vector(mesh->GetNV());
440 
441  vgf.GetNodalValues(*solx, 1);
442  vgf.GetNodalValues(*soly, 2);
443 
444  mesh->GetNodes(vc0);
445  if (vc0.Size() != vgf.Size())
446  {
447  vc0.Destroy();
448  }
449  else
450  {
451  vc0 += vgf;
452  }
453 
454  sol = new Vector(mesh->GetNV());
455  for (int i = 0; i < mesh->GetNV(); i++)
456  {
457  (*sol)(i) = Vec2Scalar((*solx)(i), (*soly)(i));
458  }
459 
461 
462  if (autoscale)
463  {
464  if (Vec2Scalar == VecLength)
465  {
466  maxlen = maxv;
467  }
468  else
469  {
470  cout << "VisualizationSceneVector::NewMeshAndSolution() : "
471  " maxlen not updated!" << endl;
472  }
473  }
474 
475  PrepareVectorField();
476 }
477 
479 {
480  drawdisp = 0;
481  drawvector = 0;
482  ArrowScale = 1.0;
483  RefineFactor = 1;
484  Vec2Scalar = VecLength;
486 
487  for (int i = 0; i < mesh->GetNV(); i++)
488  {
489  (*sol)(i) = Vec2Scalar((*solx)(i), (*soly)(i));
490  }
491 
493 
494  PrepareVectorField();
495  // PrepareDisplacedMesh(); // called by PrepareLines()
496 
497  vsvector = this;
498 
499  // static int init = 0;
500  // if (!init)
501  {
502  // init = 1;
503 
512  }
513 
514  // Vec2Scalar is VecLength
515  maxlen = maxv;
516 }
517 
519 {
520  delete sol;
521 
522  if (VecGridF)
523  {
524  delete soly;
525  delete solx;
526  }
527 }
528 
530  int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr)
531 {
532  if (drawelems < 2)
533  {
534  DenseMatrix vec_vals;
535  ElementTransformation *T;
536  DenseMatrix gv;
537  double ev[2], evec[4];
538  int vdim = VecGridF->FESpace()->GetVDim();
539  double curl_v[1];
540  Vector curl(curl_v, 1);
541 
542  VecGridF->GetVectorValues(i, ir, vec_vals, tr);
543  vals.SetSize(vec_vals.Width());
544  for (int j = 0; j < vec_vals.Width(); j++)
545  {
546  if (Vec2Scalar == VecDivSubst || Vec2Scalar == VecCurlSubst ||
547  Vec2Scalar == VecAnisotrSubst)
548  {
549  T = mesh->GetElementTransformation(i);
550  T->SetIntPoint(&ir.IntPoint(j));
551  if (Vec2Scalar == VecDivSubst)
552  {
553  vals(j) = VecGridF->GetDivergence(*T);
554  }
555  else if (Vec2Scalar == VecCurlSubst)
556  {
557  VecGridF->GetCurl(*T, curl);
558  vals(j) = curl(0);
559  }
560  else
561  {
562  if (vdim == 1)
563  {
564  vals(j) = 0.0;
565  continue;
566  }
567  VecGridF->GetVectorGradient(*T, gv);
568  if (Vec2Scalar == VecCurlSubst)
569  {
570  vals(j) = gv(1, 0) - gv(0, 1); // curl v in 2D
571  }
572  else
573  {
574  gv.Symmetrize();
575  gv.CalcEigenvalues(ev, evec);
576  vals(j) = ev[1] - ev[0];
577  // vals(j) = ev[1];
578  // vals(j) = (ev[0] <= 0.0) ? ev[0] : ev[1];
579  // vals(j) = (fabs(ev[0]) >= fabs(ev[1])) ? ev[0] : ev[1];
580  }
581  }
582  }
583  else
584  {
585  vals(j) = Vec2Scalar(vec_vals(0, j), vec_vals(1, j));
586  }
587  }
588  }
589  else
590  {
591  ElementTransformation *T = mesh->GetElementTransformation(i);
592 
593  T->Transform(ir, tr);
594 
595  vals.SetSize(ir.GetNPoints());
596  if (vc0.Size() == 0)
597  {
598  for (int j = 0; j < ir.GetNPoints(); j++)
599  {
600  T->SetIntPoint(&ir.IntPoint(j));
601  vals(j) = T->Weight();
602  }
603  }
604  else
605  {
606  mesh->GetElementTransformation(i, vc0, &T0);
607  for (int j = 0; j < ir.GetNPoints(); j++)
608  {
609  T->SetIntPoint(&ir.IntPoint(j));
610  T0.SetIntPoint(&ir.IntPoint(j));
611  vals(j) = T->Weight() / T0.Weight();
612  }
613  }
614 
615  if (drawelems == 2)
616  {
617  for (int j = 0; j < vals.Size(); j++)
618  {
619  if (vals(j) <= 0.0)
620  {
621  vals = 0.0;
622  break;
623  }
624  vals(j) = 1.0 / vals(j);
625  }
626  }
627  }
628 
629  if (logscale)
630  for (int j = 0; j < vals.Size(); j++)
631  {
632  vals(j) = _LogVal(vals(j));
633  }
634 
635  if (shrink != 1.0 || shrinkmat != 1.0)
636  {
637  ShrinkPoints(tr, i, 0, 0);
638  }
639 }
640 
642  int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr,
643  DenseMatrix &normals)
644 {
645  int have_normals = 0;
646 
647  GetRefinedValues(i, ir, vals, tr);
648 
649  return have_normals;
650 }
651 
653 {
654  int ne = mesh -> GetNE();
655  DenseMatrix pointmat;
656  Array<int> vertices;
657  double zc = 0.5*(bb.z[0]+bb.z[1]);
658 
659  // prepare the displaced mesh
660  displine_buf.clear();
661  gl3::GlBuilder build = displine_buf.createBuilder();
662  if (shading != 2)
663  {
664  for (int i = 0; i < ne; i++)
665  {
666  build.glBegin(GL_LINE_LOOP);
667  mesh->GetPointMatrix (i, pointmat);
668  mesh->GetElementVertices (i, vertices);
669 
670  for (int j = 0; j < pointmat.Size(); j++)
671  {
672  build.glVertex3d (
673  pointmat.Elem(0, j)+
674  (*solx)(vertices[j])*(ianim)/ianimmax,
675  pointmat.Elem(1, j)+
676  (*soly)(vertices[j])*(ianim)/ianimmax,
677  zc);
678  }
679  build.glEnd();
680  }
681  }
682  else if (drawdisp < 2)
683  {
684  double sc = double(ianim)/ianimmax;
685  DenseMatrix vvals, pm;
686 
687  for (int i = 0; i < ne; i++)
688  {
689  RefinedGeometry *RefG =
690  GLVisGeometryRefiner.Refine(mesh->GetElementBaseGeometry(i),
691  TimesToRefine, EdgeRefineFactor);
692  VecGridF->GetVectorValues(i, RefG->RefPts, vvals, pm);
693 
694  Array<int> &RE = RefG->RefEdges;
695  build.glBegin (GL_LINES);
696  for (int k = 0; k+1 < RE.Size(); k++)
697  {
698  build.glVertex3d (
699  pm(0, RE[k]) + sc * vvals(0, RE[k]),
700  pm(1, RE[k]) + sc * vvals(1, RE[k]), zc);
701  k++;
702  build.glVertex3d (
703  pm(0, RE[k]) + sc * vvals(0, RE[k]),
704  pm(1, RE[k]) + sc * vvals(1, RE[k]), zc);
705  }
706  build.glEnd();
707  }
708  }
709  else
710  {
711  Vector vals;
712  DenseMatrix vvals, pm;
713 
714  double x_min, x_max, y_min, y_max;
715  Array<double> levels_x, levels_y;
716 
717  x_min = y_min = numeric_limits<double>::infinity();
718  x_max = y_max = -x_min;
719 
720  for (int i = 0; i < ne; i++)
721  {
722  RefinedGeometry *RefG =
723  GLVisGeometryRefiner.Refine(mesh->GetElementBaseGeometry(i),
724  TimesToRefine, EdgeRefineFactor);
725  VecGridF->GetVectorValues(i, RefG->RefPts, vvals, pm);
726 
727  vvals += pm;
728 
729  for (int j = 0; j < vvals.Width(); j++)
730  {
731  double x = vvals(0, j), y = vvals(1, j);
732 
733  if (drawdisp == 3)
734  {
735  double phi, rho;
736  phi = atan2(y, x);
737  rho = sqrt(x * x + y * y);
738 
739  x = phi;
740  y = rho;
741  }
742 
743  if (x_min > x) { x_min = x; }
744  if (x_max < x) { x_max = x; }
745  if (y_min > y) { y_min = y; }
746  if (y_max < y) { y_max = y; }
747  }
748  }
749 
750  // define levels_x, levels_y
751  {
752  int n = level.Size()-1;
753  int nx, ny;
754  if (drawdisp == 2)
755  {
756  if ((x_max - x_min) < (y_max - y_min))
757  {
758  nx = n;
759  ny = (int)ceil(n * (y_max - y_min) / (x_max - x_min));
760  }
761  else
762  {
763  nx = (int)ceil(n * (x_max - x_min) / (y_max - y_min));
764  ny = n;
765  }
766  }
767  else
768  {
769  nx = ny = n;
770  }
771  levels_x.SetSize(nx+1);
772  levels_y.SetSize(ny+1);
773  for (int i = 0; i <= nx; i++)
774  {
775  double a = double(i) / nx;
776  levels_x[i] = (1. - a) * x_min + a * x_max;
777  }
778  double offs = 1e-3 / nx;
779  levels_x[0] = (1. - offs) * x_min + offs * x_max;
780  levels_x[nx] = offs * x_min + (1. - offs) * x_max;
781  for (int i = 0; i <= ny; i++)
782  {
783  double a = double(i) / ny;
784  levels_y[i] = (1. - a) * y_min + a * y_max;
785  }
786  offs = 1e-3 / ny;
787  levels_y[0] = (1. - offs) * y_min + offs * y_max;
788  levels_y[ny] = offs * y_min + (1. - offs) * y_max;
789  }
790 
791  for (int i = 0; i < ne; i++)
792  {
793  RefinedGeometry *RefG =
794  GLVisGeometryRefiner.Refine(mesh->GetElementBaseGeometry(i),
795  TimesToRefine, EdgeRefineFactor);
796  VecGridF->GetVectorValues(i, RefG->RefPts, vvals, pm);
797 
798  {
799  double sc = double(ianim)/ianimmax;
800  // pm = pm + sc * vvals
801  pm.Add(sc, vvals);
802  // vvals = pm + (1-sc) * vvals
803  Add(pm, vvals, 1.-sc, vvals);
804  }
805 
806  if (drawdisp == 3)
807  {
808  for (int j = 0; j < vvals.Width(); j++)
809  {
810  double x = vvals(0, j), y = vvals(1, j);
811  {
812  double phi, rho;
813  phi = atan2(y, x);
814  rho = sqrt(x * x + y * y);
815 
816  vvals(0, j) = phi;
817  vvals(1, j) = rho;
818  }
819  }
820  }
821 
822  Array<int> &RG = RefG->RefGeoms;
823  int sides = mesh->GetElement(i)->GetNVertices();
824 
825  vals.SetSize(vvals.Width());
826  for (int j = 0; j < vvals.Width(); j++)
827  {
828  vals(j) = vvals(0, j);
829  }
830  DrawLevelCurves(build, RG, pm, vals, sides, levels_x, 1);
831  for (int j = 0; j < vvals.Width(); j++)
832  {
833  vals(j) = vvals(1, j);
834  }
835  DrawLevelCurves(build, RG, pm, vals, sides, levels_y, 1);
836  }
837  }
838 
839  updated_bufs.emplace_back(&displine_buf);
840 }
841 
842 thread_local double new_maxlen;
843 
844 void VisualizationSceneVector::DrawVector(double px, double py, double vx,
845  double vy, double cval)
846 {
847  double zc = 0.5*(bb.z[0]+bb.z[1]);
848 
849  gl3::GlBuilder builder = vector_buf.createBuilder();
850 
851  if (drawvector == 1)
852  {
853  arrow_type = 0;
854  arrow_scaling_type = 0;
855  Arrow(builder, px, py, zc, vx, vy, 0.0, 1.0, 1./4./3.);
856  }
857  else if (drawvector > 0)
858  {
859  double area = (bb.x[1]-bb.x[0])*(bb.y[1]-bb.y[0]);
860  double h = sqrt(area/mesh->GetNV()) * ArrowScale;
861 
862  arrow_type = 1;
863  arrow_scaling_type = 1;
864 
865  MySetColor(builder, cval, minv, maxv);
866 
867  if (drawvector == 2)
868  {
869  Arrow(builder, px, py, zc, vx, vy, 0.0, h, 0.125);
870  }
871  else
872  {
873  double len = VecLength(vx, vy);
874  Arrow(builder, px, py, zc, vx, vy, 0.0,
875  h*max(0.01, len/maxlen), 0.125);
876  if (len > new_maxlen)
877  {
878  new_maxlen = len;
879  }
880  }
881  }
882 }
883 
885 {
886  int rerun;
887  do
888  {
889  rerun = 0;
890 
891  // glNewList(vectorlist, GL_COMPILE);
892  vector_buf.clear();
893 
894  if (drawvector > 0)
895  {
896  int i;
897 
898  palette.SetUseLogscale(logscale);
899  if (drawvector == 3)
900  {
901  new_maxlen = 0.0;
902  }
903  for (i = 0; i < mesh->GetNV(); i++)
904  {
905  double *v = mesh->GetVertex(i);
906  DrawVector(v[0], v[1], (*solx)(i), (*soly)(i), (*sol)(i));
907  }
908 
909  if (shading == 2 && RefineFactor > 1)
910  {
911  DenseMatrix vvals, pm;
912  for (i = 0; i < mesh->GetNE(); i++)
913  {
914  const IntegrationRule *ir =
915  GLVisGeometryRefiner.RefineInterior(
916  mesh->GetElementBaseGeometry(i), RefineFactor);
917  if (ir == NULL)
918  {
919  continue;
920  }
921  VecGridF->GetVectorValues(i, *ir, vvals, pm);
922  for (int j = 0; j < vvals.Width(); j++)
923  {
924  DrawVector(pm(0, j), pm(1,j), vvals(0, j), vvals(1, j),
925  Vec2Scalar(vvals(0, j), vvals(1, j)));
926  }
927  }
928  for (i = 0; i < mesh->GetNEdges(); i++)
929  {
930  const IntegrationRule *ir =
931  GLVisGeometryRefiner.RefineInterior(
932  mesh->GetFaceBaseGeometry(i), RefineFactor);
933  if (ir == NULL)
934  {
935  continue;
936  }
937  VecGridF->GetFaceVectorValues(i, 0, *ir, vvals, pm);
938  for (int j = 0; j < vvals.Width(); j++)
939  {
940  DrawVector(pm(0, j), pm(1,j), vvals(0, j), vvals(1, j),
941  Vec2Scalar(vvals(0, j), vvals(1, j)));
942  }
943  }
944  }
945 
946  if (drawvector == 3 && new_maxlen != maxlen)
947  {
948  maxlen = new_maxlen;
949  rerun = 1;
950  }
951  }
952 
953  // glEndList();
954 
955  }
956  while (rerun);
957  updated_bufs.emplace_back(&vector_buf);
958 }
959 
961 {
962  if (colorbar)
963  {
964  // update color bar before we get the base class scene
965  PrepareColorBar(minv, maxv, (drawmesh == 2) ? &level : nullptr );
966  }
968  gl3::RenderParams params = GetMeshDrawParams();
969  params.use_clip_plane = draw_cp;
970  double* cp_eqn = CuttingPlane->Equation();
971  params.clip_plane_eqn = {cp_eqn[0], cp_eqn[1], cp_eqn[2], cp_eqn[3]};
972  params.contains_translucent = false;
973  if (drawvector > 1)
974  {
975  scene.queue.emplace_back(params, &vector_buf);
976  }
977  params.contains_translucent = matAlpha < 1.0;
978  if (drawelems)
979  {
980  scene.queue.emplace_back(params, &disp_buf);
981  }
982  params.contains_translucent = false;
983  params.mesh_material = BLK_MAT;
984  params.static_color = GetLineColor();
985  if (draw_cp)
986  {
987  params.use_clip_plane = false;
988  scene.queue.emplace_back(params, &cp_buf);
989  params.use_clip_plane = true;
990  }
991  // disable lighting for objects below
992  params.num_pt_lights = 0;
993 
994  // draw boundary in 2D
995  if (drawbdr)
996  {
997  scene.queue.emplace_back(params, &bdr_buf);
998  }
999 
1000  // draw lines
1001  if (drawmesh == 1)
1002  {
1003  scene.queue.emplace_back(params, &line_buf);
1004  }
1005  else if (drawmesh == 2)
1006  {
1007  scene.queue.emplace_back(params, &lcurve_buf);
1008  }
1009 
1010  // draw numberings
1011  if (drawnums == 1)
1012  {
1013  scene.queue.emplace_back(params, &e_nums_buf);
1014  }
1015  else if (drawnums == 2)
1016  {
1017  scene.queue.emplace_back(params, &v_nums_buf);
1018  }
1019 
1020  if (drawvector == 1)
1021  {
1022  scene.queue.emplace_back(params, &vector_buf);
1023  }
1024 
1025  if (drawdisp > 0)
1026  {
1027  if (drawmesh == 1)
1028  {
1029  params.static_color = {1.f, 0.f, 0.f, 1.f};
1030  }
1031  scene.queue.emplace_back(params, &displine_buf);
1032  }
1033 
1034  return scene;
1035 }
1036 
1038 {
1039  string name = "GLVis_scene_000";
1040 
1041  glTF_Builder bld(name);
1042 
1043  auto palette_mat = AddPaletteMaterial(bld);
1044  auto pal_lines_mat = AddPaletteLinesMaterial(bld, palette_mat);
1045  auto black_mat = AddBlackMaterial(bld);
1046  auto buf = bld.addBuffer("buffer");
1047  if (drawvector)
1048  {
1049  auto vec_node = AddModelNode(bld, "Vectors");
1050  auto vec_mesh = bld.addMesh("Vectors Mesh");
1051  bld.addNodeMesh(vec_node, vec_mesh);
1052 
1053  int ntria = AddTriangles(
1054  bld,
1055  vec_mesh,
1056  buf,
1057  (drawvector == 1) ? black_mat : palette_mat,
1058  vector_buf);
1059  int nlines = AddLines(
1060  bld,
1061  vec_mesh,
1062  buf,
1063  (drawvector == 1) ? black_mat : pal_lines_mat,
1064  vector_buf);
1065  if (ntria == 0 || nlines == 0)
1066  {
1067  cout << "glTF export: no vectors found to export!" << endl;
1068  }
1069  }
1070  if (drawelems) { glTF_ExportElements(bld, buf, palette_mat, disp_buf); }
1071  if (drawmesh)
1072  {
1073  glTF_ExportMesh(bld, buf, black_mat,
1074  (drawmesh == 1) ? line_buf : lcurve_buf);
1075  }
1076  if (drawbdr) { glTF_ExportBoundary(bld, buf, black_mat); }
1077  if (drawaxes) { glTF_ExportBox(bld, buf, black_mat); }
1078  bld.writeFile();
1079 
1080  cout << "Exported glTF -> " << name << ".gltf" << endl;
1081 }
void SendExposeEvent()
Send expose event. In our case MyReshape is executed and Draw after it.
Definition: aux_vis.cpp:346
void KeyvPressed()
Definition: vsvector.cpp:141
thread_local GeometryRefiner GLVisGeometryRefiner
Definition: glvis.cpp:71
double VecLength(double x, double y)
Definition: vsvector.cpp:307
thread_local VisualizationSceneVector * vsvector
Definition: vsvector.cpp:102
void glVertex3d(double x, double y, double z)
Definition: types.hpp:332
double VecDivSubst(double x, double y)
Definition: vsvector.cpp:327
thread_local SdlWindow * wnd
Definition: aux_vis.cpp:50
double(* Vec2ScalarFunctions[7])(double, double)
Definition: vsvector.cpp:342
double VecDirection(double x, double y)
Definition: vsvector.cpp:312
void SetGridFunction(StreamState &state)
Definition: glvis.cpp:1484
void glEnd()
Definition: types.hpp:309
virtual gl3::SceneInfo GetSceneObjs()
Definition: vsdata.cpp:984
virtual ~VisualizationSceneVector()
Definition: vsvector.cpp:518
const char * Vec2ScalarNames[7]
Definition: vsvector.cpp:249
thread_local double new_maxlen
Definition: vsvector.cpp:842
thread_local int ianimmax
Definition: vsvector.cpp:108
thread_local int ianim
Definition: vsvector.cpp:107
buffer_id addBuffer(const std::string &bufferName)
Definition: gltf.cpp:24
void KeyNPressed()
Definition: vsvector.cpp:116
void glBegin(GLenum e)
Definition: types.hpp:295
void KeyDPressed()
Definition: vsvector.cpp:110
virtual std::string GetHelpString() const
Definition: vsvector.cpp:23
double VecCurlSubst(double x, double y)
Definition: vsvector.cpp:332
virtual int GetRefinedValuesAndNormals(int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr, DenseMatrix &normals)
Definition: vsvector.cpp:641
void NewMeshAndSolution(Mesh *new_m, Vector *new_sol, GridFunction *new_u=NULL)
Definition: vssolution.cpp:575
VisualizationSceneVector(Mesh &m, Vector &sx, Vector &sy)
Definition: vsvector.cpp:255
thread_local VisualizationSceneSolution * vssol
Definition: vssolution.cpp:28
mesh_id addMesh(const std::string &meshName)
Definition: gltf.cpp:322
double VecDotNx(double x, double y)
Definition: vsvector.cpp:317
void NewMeshAndSolution(GridFunction &vgf)
Definition: vsvector.cpp:406
void CycleVec2Scalar(int print=0)
Definition: vsvector.cpp:348
virtual void PrepareVectorField()
Definition: vsvector.cpp:884
virtual void GetRefinedValues(int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr)
Definition: vsvector.cpp:529
Crude fixed-function OpenGL emulation helper.
Definition: types.hpp:261
virtual gl3::SceneInfo GetSceneObjs()
Definition: vsvector.cpp:960
double VecDotNy(double x, double y)
Definition: vsvector.cpp:322
int writeFile()
Definition: gltf.cpp:472
thread_local string extra_caption
Definition: glvis.cpp:61
int key_u_func
Definition: vsvector.cpp:156
void addNodeMesh(node_id node, mesh_id mesh)
Definition: gltf.cpp:433
void DrawVector(double, double, double, double, double)
Definition: vsvector.cpp:844
virtual void ToggleDrawElems()
Definition: vsvector.cpp:223
void KeyUPressed()
Definition: vsvector.cpp:203
bool contains_translucent
Definition: renderer.hpp:55
virtual void glTF_Export()
Definition: vsvector.cpp:1037
void KeyVPressed()
Definition: vsvector.cpp:147
void KeyuPressed()
Definition: vsvector.cpp:158
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
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
void KeyBPressed()
Definition: vsvector.cpp:122
double VecAnisotrSubst(double x, double y)
Definition: vsvector.cpp:337