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
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