From 38b5b223e4b75ea6cde0edef4aa0bb8873facba7 Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Fri, 2 May 2025 13:09:49 -0700 Subject: [PATCH 01/65] Fixed the order of source files in Makefile. --- makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/makefile b/makefile index 17548919..44fb9f92 100644 --- a/makefile +++ b/makefile @@ -254,7 +254,7 @@ ALL_SOURCE_FILES = \ lib/gl/shader.cpp lib/gl/types.cpp lib/aux_js.cpp lib/aux_vis.cpp \ lib/coll_reader.cpp lib/data_state.cpp lib/file_reader.cpp \ lib/font.cpp lib/gl2ps.c lib/gltf.cpp lib/material.cpp \ - lib/openglvis.cpp lib/palettes.cpp lib/palettes_base.cpp lib/sdl.cpp \ + lib/openglvis.cpp lib/palettes_base.cpp lib/palettes.cpp lib/sdl.cpp \ lib/sdl_helper.cpp lib/sdl_main.cpp lib/sdl_windows.cpp \ lib/sdl_x11.cpp lib/stream_reader.cpp lib/threads.cpp lib/vsdata.cpp \ lib/vssolution.cpp lib/vssolution3d.cpp lib/vsvector.cpp \ @@ -275,8 +275,8 @@ HEADER_FILES = \ lib/gl/types.hpp lib/aux_vis.hpp lib/coll_reader.hpp \ lib/data_state.hpp lib/file_reader.hpp lib/font.hpp \ lib/geom_utils.hpp lib/gl2ps.h lib/gltf.hpp lib/logo.hpp \ - lib/material.hpp lib/openglvis.hpp lib/palettes.hpp \ - lib/palettes_base.hpp lib/sdl.hpp lib/sdl_helper.hpp lib/sdl_mac.hpp \ + lib/material.hpp lib/openglvis.hpp lib/palettes_base.hpp \ + lib/palettes.hpp lib/sdl_helper.hpp lib/sdl.hpp lib/sdl_mac.hpp \ lib/sdl_main.hpp lib/sdl_windows.hpp lib/sdl_x11.hpp \ lib/stream_reader.hpp lib/threads.hpp lib/visual.hpp lib/vsdata.hpp \ lib/vssolution.hpp lib/vssolution3d.hpp lib/vsvector.hpp \ From 360ca25217f77062addb8c8519dee0980d97f39c Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Fri, 2 May 2025 13:20:05 -0700 Subject: [PATCH 02/65] Separated script control functions. --- glvis.cpp | 846 +----------------------------------- lib/CMakeLists.txt | 2 + lib/script_controller.cpp | 878 ++++++++++++++++++++++++++++++++++++++ lib/script_controller.hpp | 19 + makefile | 18 +- 5 files changed, 909 insertions(+), 854 deletions(-) create mode 100644 lib/script_controller.cpp create mode 100644 lib/script_controller.hpp diff --git a/glvis.cpp b/glvis.cpp index 8c5721d3..f526fd02 100644 --- a/glvis.cpp +++ b/glvis.cpp @@ -34,6 +34,7 @@ #include "mfem.hpp" #include "lib/palettes.hpp" #include "lib/visual.hpp" +#include "lib/script_controller.hpp" #include "lib/stream_reader.hpp" #include "lib/file_reader.hpp" #include "lib/coll_reader.hpp" @@ -91,14 +92,6 @@ const char *window_titles[] = { "GLVis [mesh]", "GLVis [scalar data]", "GLVis [vector data]", }; -istream *script = NULL; -int scr_running = 0; -int scr_level = 0; -Vector *init_nodes = NULL; -double scr_min_val, scr_max_val; - -extern char **environ; - void PrintSampleUsage(ostream &out); @@ -282,843 +275,6 @@ void GLVisStartVis() cout << "GLVis window closed." << endl; } -int ScriptReadSolution(istream &scr, DataState& state) -{ - int err_read; - string mword,sword; - - cout << "Script: solution: " << flush; - // read the mesh - scr >> ws >> mword; // mesh filename (can't contain spaces) - cout << "mesh: " << mword << "; " << flush; - named_ifgzstream imesh(mword.c_str()); - if (!imesh) - { - cout << "Can not open mesh file: " << mword << endl; - return 1; - } - state.SetMesh(new Mesh(imesh, 1, 0, state.fix_elem_orient)); - - // read the solution (GridFunction) - scr >> ws >> sword; - cout << "solution: " << sword << endl; - - FileReader reader(state); - err_read = reader.ReadSerial(FileReader::FileType::GRID_FUNC, mword.c_str(), - sword.c_str()); - - return err_read; -} - -int ScriptReadQuadrature(istream &scr, DataState& state) -{ - int err_read; - string mword,sword; - - cout << "Script: quadrature: " << flush; - // read the mesh - scr >> ws >> mword; // mesh filename (can't contain spaces) - cout << "mesh: " << mword << "; " << flush; - named_ifgzstream imesh(mword.c_str()); - if (!imesh) - { - cout << "Can not open mesh file: " << mword << endl; - return 1; - } - state.SetMesh(new Mesh(imesh, 1, 0, state.fix_elem_orient)); - - // read the quadrature (QuadratureFunction) - scr >> ws >> sword; - cout << "quadrature: " << sword << endl; - - FileReader reader(state); - err_read = reader.ReadSerial(FileReader::FileType::QUAD_FUNC, mword.c_str(), - sword.c_str()); - - return err_read; -} - -int ScriptReadParSolution(istream &scr, DataState& state) -{ - int np, scr_keep_attr, err_read; - string mesh_prefix, sol_prefix; - - cout << "Script: psolution: " << flush; - // read number of processors - scr >> np; - cout << "# processors: " << np << "; " << flush; - // read the mesh prefix - scr >> ws >> mesh_prefix; // mesh prefix (can't contain spaces) - cout << "mesh prefix: " << mesh_prefix << "; " << flush; - scr >> ws >> scr_keep_attr; - if (scr_keep_attr) - { - cout << "(real attributes); " << flush; - } - else - { - cout << "(processor attributes); " << flush; - } - // read the solution prefix - scr >> ws >> sol_prefix; - cout << "solution prefix: " << sol_prefix << endl; - - FileReader reader(state); - err_read = reader.ReadParallel(np, FileReader::FileType::GRID_FUNC, - mesh_prefix.c_str(), sol_prefix.c_str()); - return err_read; -} - -int ScriptReadParQuadrature(istream &scr, DataState& state) -{ - int np, scr_keep_attr, err_read; - string mesh_prefix, quad_prefix; - - cout << "Script: pquadrature: " << flush; - // read number of processors - scr >> np; - cout << "# processors: " << np << "; " << flush; - // read the mesh prefix - scr >> ws >> mesh_prefix; // mesh prefix (can't contain spaces) - cout << "mesh prefix: " << mesh_prefix << "; " << flush; - scr >> ws >> scr_keep_attr; - if (scr_keep_attr) - { - cout << "(real attributes); " << flush; - } - else - { - cout << "(processor attributes); " << flush; - } - // read the quadrature prefix - scr >> ws >> quad_prefix; - cout << "quadrature prefix: " << quad_prefix << endl; - - FileReader reader(state); - err_read = reader.ReadParallel(np, FileReader::FileType::QUAD_FUNC, - mesh_prefix.c_str(), quad_prefix.c_str()); - return err_read; -} - -int ScriptReadDisplMesh(istream &scr, DataState& state) -{ - DataState meshstate; - string word; - - cout << "Script: mesh: " << flush; - scr >> ws >> word; - { - named_ifgzstream imesh(word.c_str()); - if (!imesh) - { - cout << "Can not open mesh file: " << word << endl; - return 1; - } - cout << word << endl; - meshstate.SetMesh(new Mesh(imesh, 1, 0, state.fix_elem_orient)); - } - meshstate.ExtrudeMeshAndSolution(); - Mesh* const m = meshstate.mesh.get(); - if (init_nodes == NULL) - { - init_nodes = new Vector; - meshstate.mesh->GetNodes(*init_nodes); - state.SetMesh(NULL); - state.SetGridFunction(NULL); - } - else - { - FiniteElementCollection *vfec = NULL; - FiniteElementSpace *vfes; - vfes = (FiniteElementSpace *)m->GetNodalFESpace(); - if (vfes == NULL) - { - vfec = new LinearFECollection; - vfes = new FiniteElementSpace(m, vfec, m->SpaceDimension()); - } - - meshstate.SetGridFunction(new GridFunction(vfes)); - GridFunction * const g = meshstate.grid_f.get(); - if (vfec) - { - g->MakeOwner(vfec); - } - m->GetNodes(*g); - if (g->Size() == init_nodes->Size()) - { - subtract(*init_nodes, *g, *g); - } - else - { - cout << "Script: incompatible meshes!" << endl; - *g = 0.0; - } - - state = std::move(meshstate); - } - - return 0; -} - -int ScriptReadDataColl(istream &scr, DataState &state, bool mesh_only = true, - bool quad = false) -{ - int err_read; - int type; - string cword, fword; - - cout << "Script: data_collection: " << flush; - // read the collection - scr >> ws >> type; // collection type - cout << "type: " << type << "; " << flush; - scr >> ws >> cword; // collection filename (can't contain spaces) - cout << "collection: " << cword << "; " << flush; - - if (!mesh_only) - { - // read the field - scr >> ws >> fword; - cout << "field: " << fword << endl; - } - - DataCollectionReader reader(state); - if (dc_protocol != string_default) - { - reader.SetProtocol(dc_protocol.c_str()); - } - - if (mesh_only) - err_read = reader.ReadSerial((DataCollectionReader::CollType)type, - cword.c_str(), dc_cycle); - else - err_read = reader.ReadSerial((DataCollectionReader::CollType)type, - cword.c_str(), dc_cycle, fword.c_str(), quad); - - return err_read; -} - -void ExecuteScriptCommand() -{ - if (!script) - { - cout << "No script stream defined! (Bug?)" << endl; - return; - } - - istream &scr = *script; - string word; - int done_one_command = 0; - while (!done_one_command) - { - scr >> ws; - if (!scr.good()) - { - cout << "End of script." << endl; - scr_level = 0; - return; - } - if (scr.peek() == '#') - { - getline(scr, word); - continue; - } - scr >> word; - if (word == "{") - { - scr_level++; - } - else if (word == "}") - { - scr_level--; - if (scr_level < 0) - { - scr_level = 0; - } - } - else if (word == "data_coll_cycle") - { - scr >> dc_cycle; - } - else if (word == "data_coll_protocol") - { - scr >> dc_protocol; - } - else if (word == "solution" || word == "mesh" || word == "psolution" - || word == "quadrature" || word == "pquadrature" || word == "data_coll_mesh" - || word == "data_coll_field" || word == "data_coll_quad") - { - DataState new_state; - - if (word == "solution") - { - if (ScriptReadSolution(scr, new_state)) - { - done_one_command = 1; - continue; - } - } - else if (word == "quadrature") - { - if (ScriptReadQuadrature(scr, new_state)) - { - done_one_command = 1; - continue; - } - } - else if (word == "mesh") - { - if (ScriptReadDisplMesh(scr, new_state)) - { - done_one_command = 1; - continue; - } - if (new_state.mesh == NULL) - { - cout << "Script: unexpected 'mesh' command!" << endl; - done_one_command = 1; - continue; - } - } - else if (word == "psolution") - { - if (ScriptReadParSolution(scr, new_state)) - { - done_one_command = 1; - continue; - } - } - else if (word == "pquadrature") - { - if (ScriptReadParQuadrature(scr, new_state)) - { - done_one_command = 1; - continue; - } - } - else if (word == "data_coll_mesh") - { - if (ScriptReadDataColl(scr, new_state)) - { - done_one_command = 1; - continue; - } - } - else if (word == "data_coll_field") - { - if (ScriptReadDataColl(scr, new_state, false)) - { - done_one_command = 1; - continue; - } - } - else if (word == "data_coll_quad") - { - if (ScriptReadDataColl(scr, new_state, false, true)) - { - done_one_command = 1; - continue; - } - } - - if (stream_state.SetNewMeshAndSolution(std::move(new_state), vs)) - { - MyExpose(); - } - else - { - cout << "Different type of mesh / solution." << endl; - } - } - else if (word == "screenshot") - { - scr >> ws >> word; - - cout << "Script: screenshot: " << flush; - - if (Screenshot(word.c_str(), true)) - { - cout << "Screenshot(" << word << ") failed." << endl; - done_one_command = 1; - continue; - } - cout << "-> " << word << endl; - - if (scr_min_val > vs->GetMinV()) - { - scr_min_val = vs->GetMinV(); - } - if (scr_max_val < vs->GetMaxV()) - { - scr_max_val = vs->GetMaxV(); - } - } - else if (word == "viewcenter") - { - scr >> vs->ViewCenterX >> vs->ViewCenterY; - cout << "Script: viewcenter: " - << vs->ViewCenterX << ' ' << vs->ViewCenterY << endl; - MyExpose(); - } - else if (word == "perspective") - { - scr >> ws >> word; - cout << "Script: perspective: " << word; - if (word == "off") - { - vs->OrthogonalProjection = 1; - } - else if (word == "on") - { - vs->OrthogonalProjection = 0; - } - else - { - cout << '?'; - } - cout << endl; - MyExpose(); - } - else if (word == "light") - { - scr >> ws >> word; - cout << "Script: light: " << word; - if (word == "off") - { - vs->SetLight(false); - } - else if (word == "on") - { - vs->SetLight(true); - } - else - { - cout << '?'; - } - cout << endl; - MyExpose(); - } - else if (word == "view") - { - double theta, phi; - scr >> theta >> phi; - cout << "Script: view: " << theta << ' ' << phi << endl; - vs->SetView(theta, phi); - MyExpose(); - } - else if (word == "zoom") - { - double factor; - scr >> factor; - cout << "Script: zoom: " << factor << endl; - vs->Zoom(factor); - MyExpose(); - } - else if (word == "shading") - { - scr >> ws >> word; - cout << "Script: shading: " << flush; - VisualizationSceneScalarData::Shading s = - VisualizationSceneScalarData::Shading::Invalid; - if (word == "flat") - { - s = VisualizationSceneScalarData::Shading::Flat; - } - else if (word == "smooth") - { - s = VisualizationSceneScalarData::Shading::Smooth; - } - else if (word == "cool") - { - s = VisualizationSceneScalarData::Shading::Noncomforming; - } - if (s != VisualizationSceneScalarData::Shading::Invalid) - { - vs->SetShading(s, false); - cout << word << endl; - MyExpose(); - } - else - { - cout << word << " ?" << endl; - } - } - else if (word == "subdivisions") - { - int t, b; - scr >> t >> b; - cout << "Script: subdivisions: " << flush; - vs->SetRefineFactors(t, b); - cout << t << ' ' << b << endl; - MyExpose(); - } - else if (word == "valuerange") - { - double min, max; - scr >> min >> max; - cout << "Script: valuerange: " << flush; - vs->SetValueRange(min, max); - cout << min << ' ' << max << endl; - MyExpose(); - } - else if (word == "autoscale") - { - scr >> ws >> word; - cout << "Script: autoscale: " << word; - if (word == "off") - { - vs->SetAutoscale(0); - } - else if (word == "on") - { - vs->SetAutoscale(1); - } - else if (word == "value") - { - vs->SetAutoscale(2); - } - else if (word == "mesh") - { - vs->SetAutoscale(3); - } - else - { - cout << '?'; - } - cout << endl; - } - else if (word == "levellines") - { - double min, max; - int num; - scr >> min >> max >> num; - cout << "Script: levellines: " << flush; - vs->SetLevelLines(min, max, num); - vs->UpdateLevelLines(); - cout << min << ' ' << max << ' ' << num << endl; - MyExpose(); - } - else if (word == "axis_numberformat") - { - char delim; - string axis_formatting; - scr >> ws >> delim; - getline(scr, axis_formatting, delim); - cout << "Script: axis_numberformat: " << flush; - vs->SetAxisNumberFormat(axis_formatting); - cout << axis_formatting << endl; - MyExpose(); - } - else if (word == "colorbar_numberformat") - { - char delim; - string colorbar_formatting; - scr >> ws >> delim; - getline(scr, colorbar_formatting, delim); - cout << "Script: colorbar_numberformat: " << flush; - vs->SetColorbarNumberFormat(colorbar_formatting); - cout << colorbar_formatting << endl; - MyExpose(); - } - else if (word == "window") - { - scr >> window_x >> window_y >> window_w >> window_h; - cout << "Script: window: " << window_x << ' ' << window_y - << ' ' << window_w << ' ' << window_h << endl; - MoveResizeWindow(window_x, window_y, window_w, window_h); - MyExpose(); - } - else if (word == "keys") - { - scr >> stream_state.keys; - cout << "Script: keys: '" << stream_state.keys << "'" << endl; - // SendKeySequence(keys.c_str()); - CallKeySequence(stream_state.keys.c_str()); - MyExpose(); - } - else if (word == "palette") - { - int pal; - scr >> pal; - cout << "Script: palette: " << pal << endl; - vs->palette.SetIndex(pal-1); - MyExpose(); - } - else if (word == "palette_repeat") - { - int rpt_times; - scr >> rpt_times; - cout << "Script: palette_repeat: " << rpt_times << endl; - vs->palette.SetRepeatTimes(rpt_times); - vs->palette.GenerateTextures(); - MyExpose(); - } - else if (word == "toggle_attributes") - { - Array attr_list; - cout << "Script: toggle_attributes:"; - for (scr >> ws; scr.peek() != ';'; scr >> ws) - { - attr_list.Append(0); - scr >> attr_list.Last(); - if (attr_list.Size() <= 256) - { - cout << ' ' << attr_list.Last(); - } - else if (attr_list.Size() == 257) - { - cout << " ... " << flush; - } - } - scr.get(); // read the end symbol: ';' - cout << endl; - vs->ToggleAttributes(attr_list); - MyExpose(); - } - else if (word == "rotmat") - { - cout << "Script: rotmat:"; - for (int i = 0; i < 16; i++) - { - scr >> vs->rotmat[i/4][i%4]; - cout << ' ' << vs->rotmat[i/4][i%4]; - } - cout << endl; - MyExpose(); - } - else if (word == "camera") - { - double cam[9]; - cout << "Script: camera:"; - for (int i = 0; i < 9; i++) - { - scr >> cam[i]; - cout << ' ' << cam[i]; - } - cout << endl; - vs->cam.Set(cam); - MyExpose(); - } - else if (word == "scale") - { - double scale; - cout << "Script: scale:"; - scr >> scale; - cout << ' ' << scale; - cout << endl; - vs->Scale(scale); - MyExpose(); - } - else if (word == "translate") - { - double x, y, z; - cout << "Script: translate:"; - scr >> x >> y >> z; - cout << ' ' << x << ' ' << y << ' ' << z; - cout << endl; - vs->Translate(x, y, z); - MyExpose(); - } - else if (word == "plot_caption") - { - char delim; - scr >> ws >> delim; - getline(scr, plot_caption, delim); - vs->PrepareCaption(); // turn on or off the caption - MyExpose(); - } - else - { - cout << "Unknown command in script: " << word << endl; - } - - done_one_command = 1; - } -} - -void ScriptControl(); - -void ScriptIdleFunc() -{ - ExecuteScriptCommand(); - if (scr_level == 0) - { - ScriptControl(); - } -} - -void ScriptControl() -{ - if (scr_running) - { - scr_running = 0; - RemoveIdleFunc(ScriptIdleFunc); - } - else - { - scr_running = 1; - AddIdleFunc(ScriptIdleFunc); - } -} - -void PlayScript(istream &scr) -{ - string word; - - scr_min_val = numeric_limits::infinity(); - scr_max_val = -scr_min_val; - - // read initializing commands - while (1) - { - scr >> ws; - if (!scr.good()) - { - cout << "Error in script" << endl; - return; - } - if (scr.peek() == '#') - { - getline(scr, word); - continue; - } - scr >> word; - if (word == "window") - { - scr >> window_x >> window_y >> window_w >> window_h; - } - else if (word == "data_coll_cycle") - { - scr >> dc_cycle; - } - else if (word == "data_coll_protocol") - { - scr >> dc_protocol; - } - else if (word == "solution") - { - if (ScriptReadSolution(scr, stream_state)) - { - return; - } - - // start the visualization - break; - } - else if (word == "quadrature") - { - if (ScriptReadQuadrature(scr, stream_state)) - { - return; - } - - // start the visualization - break; - } - else if (word == "psolution") - { - if (ScriptReadParSolution(scr, stream_state)) - { - return; - } - - // start the visualization - break; - } - else if (word == "pquadrature") - { - if (ScriptReadParQuadrature(scr, stream_state)) - { - return; - } - - // start the visualization - break; - } - else if (word == "mesh") - { - if (ScriptReadDisplMesh(scr, stream_state)) - { - return; - } - if (stream_state.mesh) - { - break; - } - } - else if (word == "data_coll_mesh") - { - if (ScriptReadDataColl(scr, stream_state)) - { - return; - } - - // start the visualization - break; - } - else if (word == "data_coll_field") - { - if (ScriptReadDataColl(scr, stream_state, false)) - { - return; - } - - // start the visualization - break; - } - else if (word == "data_coll_quad") - { - if (ScriptReadDataColl(scr, stream_state, false, true)) - { - return; - } - - // start the visualization - break; - } - else - { - cout << "Unknown command in script: " << word << endl; - } - } - - scr_level = scr_running = 0; - script = &scr; - stream_state.keys.clear(); - - // Make sure the singleton object returned by GetMainThread() is - // initialized from the main thread. - GetMainThread(); - - std::thread worker_thread - { - [&](DataState local_state) - { - // set the thread-local DataState - stream_state = std::move(local_state); - if (c_plot_caption != string_none) - { - plot_caption = c_plot_caption; - } - if (GLVisInitVis({})) - { - GetAppWindow()->setOnKeyDown(SDLK_SPACE, ScriptControl); - GLVisStartVis(); - } - }, - std::move(stream_state) - }; - - SDLMainLoop(); - worker_thread.join(); - - delete init_nodes; init_nodes = NULL; - - cout << "Script: min_val = " << scr_min_val - << ", max_val = " << scr_max_val << endl; - - script = NULL; -} - class Session { StreamCollection input_streams; diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index a3e65200..5654f430 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -24,6 +24,7 @@ list(APPEND SOURCES openglvis.cpp palettes.cpp palettes_base.cpp + script_controller.cpp sdl.cpp sdl_helper.cpp sdl_main.cpp @@ -53,6 +54,7 @@ list(APPEND HEADERS openglvis.hpp palettes.hpp palettes_base.hpp + script_controller.hpp sdl.hpp sdl_helper.hpp sdl_main.hpp diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp new file mode 100644 index 00000000..55b166ea --- /dev/null +++ b/lib/script_controller.cpp @@ -0,0 +1,878 @@ +// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced +// at the Lawrence Livermore National Laboratory. All Rights reserved. See files +// LICENSE and NOTICE for details. LLNL-CODE-443271. +// +// This file is part of the GLVis visualization tool and library. For more +// information and source code availability see https://glvis.org. +// +// GLVis is free software; you can redistribute it and/or modify it under the +// terms of the BSD-3 license. We welcome feedback and contributions, see file +// CONTRIBUTING.md for details. + +#include "file_reader.hpp" +#include "coll_reader.hpp" +#include "stream_reader.hpp" +#include "visual.hpp" + +using namespace std; +using namespace mfem; + +extern const char *string_none; +extern const char *string_default; + +extern string dc_protocol; +extern int dc_cycle; +extern int window_x; +extern int window_y; +extern int window_w; +extern int window_h; +extern const char *c_plot_caption; + +extern thread_local DataState stream_state; +extern thread_local VisualizationSceneScalarData *vs; + +istream *script = NULL; +int scr_running = 0; +int scr_level = 0; +Vector *init_nodes = NULL; +double scr_min_val, scr_max_val; + +bool GLVisInitVis(StreamCollection input_streams); +void GLVisStartVis(); + +int ScriptReadSolution(istream &scr, DataState& state) +{ + int err_read; + string mword,sword; + + cout << "Script: solution: " << flush; + // read the mesh + scr >> ws >> mword; // mesh filename (can't contain spaces) + cout << "mesh: " << mword << "; " << flush; + named_ifgzstream imesh(mword.c_str()); + if (!imesh) + { + cout << "Can not open mesh file: " << mword << endl; + return 1; + } + state.SetMesh(new Mesh(imesh, 1, 0, state.fix_elem_orient)); + + // read the solution (GridFunction) + scr >> ws >> sword; + cout << "solution: " << sword << endl; + + FileReader reader(state); + err_read = reader.ReadSerial(FileReader::FileType::GRID_FUNC, mword.c_str(), + sword.c_str()); + + return err_read; +} + +int ScriptReadQuadrature(istream &scr, DataState& state) +{ + int err_read; + string mword,sword; + + cout << "Script: quadrature: " << flush; + // read the mesh + scr >> ws >> mword; // mesh filename (can't contain spaces) + cout << "mesh: " << mword << "; " << flush; + named_ifgzstream imesh(mword.c_str()); + if (!imesh) + { + cout << "Can not open mesh file: " << mword << endl; + return 1; + } + state.SetMesh(new Mesh(imesh, 1, 0, state.fix_elem_orient)); + + // read the quadrature (QuadratureFunction) + scr >> ws >> sword; + cout << "quadrature: " << sword << endl; + + FileReader reader(state); + err_read = reader.ReadSerial(FileReader::FileType::QUAD_FUNC, mword.c_str(), + sword.c_str()); + + return err_read; +} + +int ScriptReadParSolution(istream &scr, DataState& state) +{ + int np, scr_keep_attr, err_read; + string mesh_prefix, sol_prefix; + + cout << "Script: psolution: " << flush; + // read number of processors + scr >> np; + cout << "# processors: " << np << "; " << flush; + // read the mesh prefix + scr >> ws >> mesh_prefix; // mesh prefix (can't contain spaces) + cout << "mesh prefix: " << mesh_prefix << "; " << flush; + scr >> ws >> scr_keep_attr; + if (scr_keep_attr) + { + cout << "(real attributes); " << flush; + } + else + { + cout << "(processor attributes); " << flush; + } + // read the solution prefix + scr >> ws >> sol_prefix; + cout << "solution prefix: " << sol_prefix << endl; + + FileReader reader(state); + err_read = reader.ReadParallel(np, FileReader::FileType::GRID_FUNC, + mesh_prefix.c_str(), sol_prefix.c_str()); + return err_read; +} + +int ScriptReadParQuadrature(istream &scr, DataState& state) +{ + int np, scr_keep_attr, err_read; + string mesh_prefix, quad_prefix; + + cout << "Script: pquadrature: " << flush; + // read number of processors + scr >> np; + cout << "# processors: " << np << "; " << flush; + // read the mesh prefix + scr >> ws >> mesh_prefix; // mesh prefix (can't contain spaces) + cout << "mesh prefix: " << mesh_prefix << "; " << flush; + scr >> ws >> scr_keep_attr; + if (scr_keep_attr) + { + cout << "(real attributes); " << flush; + } + else + { + cout << "(processor attributes); " << flush; + } + // read the quadrature prefix + scr >> ws >> quad_prefix; + cout << "quadrature prefix: " << quad_prefix << endl; + + FileReader reader(state); + err_read = reader.ReadParallel(np, FileReader::FileType::QUAD_FUNC, + mesh_prefix.c_str(), quad_prefix.c_str()); + return err_read; +} + +int ScriptReadDisplMesh(istream &scr, DataState& state) +{ + DataState meshstate; + string word; + + cout << "Script: mesh: " << flush; + scr >> ws >> word; + { + named_ifgzstream imesh(word.c_str()); + if (!imesh) + { + cout << "Can not open mesh file: " << word << endl; + return 1; + } + cout << word << endl; + meshstate.SetMesh(new Mesh(imesh, 1, 0, state.fix_elem_orient)); + } + meshstate.ExtrudeMeshAndSolution(); + Mesh* const m = meshstate.mesh.get(); + if (init_nodes == NULL) + { + init_nodes = new Vector; + meshstate.mesh->GetNodes(*init_nodes); + state.SetMesh(NULL); + state.SetGridFunction(NULL); + } + else + { + FiniteElementCollection *vfec = NULL; + FiniteElementSpace *vfes; + vfes = (FiniteElementSpace *)m->GetNodalFESpace(); + if (vfes == NULL) + { + vfec = new LinearFECollection; + vfes = new FiniteElementSpace(m, vfec, m->SpaceDimension()); + } + + meshstate.SetGridFunction(new GridFunction(vfes)); + GridFunction * const g = meshstate.grid_f.get(); + if (vfec) + { + g->MakeOwner(vfec); + } + m->GetNodes(*g); + if (g->Size() == init_nodes->Size()) + { + subtract(*init_nodes, *g, *g); + } + else + { + cout << "Script: incompatible meshes!" << endl; + *g = 0.0; + } + + state = std::move(meshstate); + } + + return 0; +} + +int ScriptReadDataColl(istream &scr, DataState &state, bool mesh_only = true, + bool quad = false) +{ + int err_read; + int type; + string cword, fword; + + cout << "Script: data_collection: " << flush; + // read the collection + scr >> ws >> type; // collection type + cout << "type: " << type << "; " << flush; + scr >> ws >> cword; // collection filename (can't contain spaces) + cout << "collection: " << cword << "; " << flush; + + if (!mesh_only) + { + // read the field + scr >> ws >> fword; + cout << "field: " << fword << endl; + } + + DataCollectionReader reader(state); + if (dc_protocol != string_default) + { + reader.SetProtocol(dc_protocol.c_str()); + } + + if (mesh_only) + err_read = reader.ReadSerial((DataCollectionReader::CollType)type, + cword.c_str(), dc_cycle); + else + err_read = reader.ReadSerial((DataCollectionReader::CollType)type, + cword.c_str(), dc_cycle, fword.c_str(), quad); + + return err_read; +} + +void ExecuteScriptCommand() +{ + if (!script) + { + cout << "No script stream defined! (Bug?)" << endl; + return; + } + + istream &scr = *script; + string word; + int done_one_command = 0; + while (!done_one_command) + { + scr >> ws; + if (!scr.good()) + { + cout << "End of script." << endl; + scr_level = 0; + return; + } + if (scr.peek() == '#') + { + getline(scr, word); + continue; + } + scr >> word; + if (word == "{") + { + scr_level++; + } + else if (word == "}") + { + scr_level--; + if (scr_level < 0) + { + scr_level = 0; + } + } + else if (word == "data_coll_cycle") + { + scr >> dc_cycle; + } + else if (word == "data_coll_protocol") + { + scr >> dc_protocol; + } + else if (word == "solution" || word == "mesh" || word == "psolution" + || word == "quadrature" || word == "pquadrature" || word == "data_coll_mesh" + || word == "data_coll_field" || word == "data_coll_quad") + { + DataState new_state; + + if (word == "solution") + { + if (ScriptReadSolution(scr, new_state)) + { + done_one_command = 1; + continue; + } + } + else if (word == "quadrature") + { + if (ScriptReadQuadrature(scr, new_state)) + { + done_one_command = 1; + continue; + } + } + else if (word == "mesh") + { + if (ScriptReadDisplMesh(scr, new_state)) + { + done_one_command = 1; + continue; + } + if (new_state.mesh == NULL) + { + cout << "Script: unexpected 'mesh' command!" << endl; + done_one_command = 1; + continue; + } + } + else if (word == "psolution") + { + if (ScriptReadParSolution(scr, new_state)) + { + done_one_command = 1; + continue; + } + } + else if (word == "pquadrature") + { + if (ScriptReadParQuadrature(scr, new_state)) + { + done_one_command = 1; + continue; + } + } + else if (word == "data_coll_mesh") + { + if (ScriptReadDataColl(scr, new_state)) + { + done_one_command = 1; + continue; + } + } + else if (word == "data_coll_field") + { + if (ScriptReadDataColl(scr, new_state, false)) + { + done_one_command = 1; + continue; + } + } + else if (word == "data_coll_quad") + { + if (ScriptReadDataColl(scr, new_state, false, true)) + { + done_one_command = 1; + continue; + } + } + + if (stream_state.SetNewMeshAndSolution(std::move(new_state), vs)) + { + MyExpose(); + } + else + { + cout << "Different type of mesh / solution." << endl; + } + } + else if (word == "screenshot") + { + scr >> ws >> word; + + cout << "Script: screenshot: " << flush; + + if (Screenshot(word.c_str(), true)) + { + cout << "Screenshot(" << word << ") failed." << endl; + done_one_command = 1; + continue; + } + cout << "-> " << word << endl; + + if (scr_min_val > vs->GetMinV()) + { + scr_min_val = vs->GetMinV(); + } + if (scr_max_val < vs->GetMaxV()) + { + scr_max_val = vs->GetMaxV(); + } + } + else if (word == "viewcenter") + { + scr >> vs->ViewCenterX >> vs->ViewCenterY; + cout << "Script: viewcenter: " + << vs->ViewCenterX << ' ' << vs->ViewCenterY << endl; + MyExpose(); + } + else if (word == "perspective") + { + scr >> ws >> word; + cout << "Script: perspective: " << word; + if (word == "off") + { + vs->OrthogonalProjection = 1; + } + else if (word == "on") + { + vs->OrthogonalProjection = 0; + } + else + { + cout << '?'; + } + cout << endl; + MyExpose(); + } + else if (word == "light") + { + scr >> ws >> word; + cout << "Script: light: " << word; + if (word == "off") + { + vs->SetLight(false); + } + else if (word == "on") + { + vs->SetLight(true); + } + else + { + cout << '?'; + } + cout << endl; + MyExpose(); + } + else if (word == "view") + { + double theta, phi; + scr >> theta >> phi; + cout << "Script: view: " << theta << ' ' << phi << endl; + vs->SetView(theta, phi); + MyExpose(); + } + else if (word == "zoom") + { + double factor; + scr >> factor; + cout << "Script: zoom: " << factor << endl; + vs->Zoom(factor); + MyExpose(); + } + else if (word == "shading") + { + scr >> ws >> word; + cout << "Script: shading: " << flush; + VisualizationSceneScalarData::Shading s = + VisualizationSceneScalarData::Shading::Invalid; + if (word == "flat") + { + s = VisualizationSceneScalarData::Shading::Flat; + } + else if (word == "smooth") + { + s = VisualizationSceneScalarData::Shading::Smooth; + } + else if (word == "cool") + { + s = VisualizationSceneScalarData::Shading::Noncomforming; + } + if (s != VisualizationSceneScalarData::Shading::Invalid) + { + vs->SetShading(s, false); + cout << word << endl; + MyExpose(); + } + else + { + cout << word << " ?" << endl; + } + } + else if (word == "subdivisions") + { + int t, b; + scr >> t >> b; + cout << "Script: subdivisions: " << flush; + vs->SetRefineFactors(t, b); + cout << t << ' ' << b << endl; + MyExpose(); + } + else if (word == "valuerange") + { + double min, max; + scr >> min >> max; + cout << "Script: valuerange: " << flush; + vs->SetValueRange(min, max); + cout << min << ' ' << max << endl; + MyExpose(); + } + else if (word == "autoscale") + { + scr >> ws >> word; + cout << "Script: autoscale: " << word; + if (word == "off") + { + vs->SetAutoscale(0); + } + else if (word == "on") + { + vs->SetAutoscale(1); + } + else if (word == "value") + { + vs->SetAutoscale(2); + } + else if (word == "mesh") + { + vs->SetAutoscale(3); + } + else + { + cout << '?'; + } + cout << endl; + } + else if (word == "levellines") + { + double min, max; + int num; + scr >> min >> max >> num; + cout << "Script: levellines: " << flush; + vs->SetLevelLines(min, max, num); + vs->UpdateLevelLines(); + cout << min << ' ' << max << ' ' << num << endl; + MyExpose(); + } + else if (word == "axis_numberformat") + { + char delim; + string axis_formatting; + scr >> ws >> delim; + getline(scr, axis_formatting, delim); + cout << "Script: axis_numberformat: " << flush; + vs->SetAxisNumberFormat(axis_formatting); + cout << axis_formatting << endl; + MyExpose(); + } + else if (word == "colorbar_numberformat") + { + char delim; + string colorbar_formatting; + scr >> ws >> delim; + getline(scr, colorbar_formatting, delim); + cout << "Script: colorbar_numberformat: " << flush; + vs->SetColorbarNumberFormat(colorbar_formatting); + cout << colorbar_formatting << endl; + MyExpose(); + } + else if (word == "window") + { + scr >> window_x >> window_y >> window_w >> window_h; + cout << "Script: window: " << window_x << ' ' << window_y + << ' ' << window_w << ' ' << window_h << endl; + MoveResizeWindow(window_x, window_y, window_w, window_h); + MyExpose(); + } + else if (word == "keys") + { + scr >> stream_state.keys; + cout << "Script: keys: '" << stream_state.keys << "'" << endl; + // SendKeySequence(keys.c_str()); + CallKeySequence(stream_state.keys.c_str()); + MyExpose(); + } + else if (word == "palette") + { + int pal; + scr >> pal; + cout << "Script: palette: " << pal << endl; + vs->palette.SetIndex(pal-1); + MyExpose(); + } + else if (word == "palette_repeat") + { + int rpt_times; + scr >> rpt_times; + cout << "Script: palette_repeat: " << rpt_times << endl; + vs->palette.SetRepeatTimes(rpt_times); + vs->palette.GenerateTextures(); + MyExpose(); + } + else if (word == "toggle_attributes") + { + Array attr_list; + cout << "Script: toggle_attributes:"; + for (scr >> ws; scr.peek() != ';'; scr >> ws) + { + attr_list.Append(0); + scr >> attr_list.Last(); + if (attr_list.Size() <= 256) + { + cout << ' ' << attr_list.Last(); + } + else if (attr_list.Size() == 257) + { + cout << " ... " << flush; + } + } + scr.get(); // read the end symbol: ';' + cout << endl; + vs->ToggleAttributes(attr_list); + MyExpose(); + } + else if (word == "rotmat") + { + cout << "Script: rotmat:"; + for (int i = 0; i < 16; i++) + { + scr >> vs->rotmat[i/4][i%4]; + cout << ' ' << vs->rotmat[i/4][i%4]; + } + cout << endl; + MyExpose(); + } + else if (word == "camera") + { + double cam[9]; + cout << "Script: camera:"; + for (int i = 0; i < 9; i++) + { + scr >> cam[i]; + cout << ' ' << cam[i]; + } + cout << endl; + vs->cam.Set(cam); + MyExpose(); + } + else if (word == "scale") + { + double scale; + cout << "Script: scale:"; + scr >> scale; + cout << ' ' << scale; + cout << endl; + vs->Scale(scale); + MyExpose(); + } + else if (word == "translate") + { + double x, y, z; + cout << "Script: translate:"; + scr >> x >> y >> z; + cout << ' ' << x << ' ' << y << ' ' << z; + cout << endl; + vs->Translate(x, y, z); + MyExpose(); + } + else if (word == "plot_caption") + { + char delim; + scr >> ws >> delim; + getline(scr, plot_caption, delim); + vs->PrepareCaption(); // turn on or off the caption + MyExpose(); + } + else + { + cout << "Unknown command in script: " << word << endl; + } + + done_one_command = 1; + } +} + +void ScriptControl(); + +void ScriptIdleFunc() +{ + ExecuteScriptCommand(); + if (scr_level == 0) + { + ScriptControl(); + } +} + +void ScriptControl() +{ + if (scr_running) + { + scr_running = 0; + RemoveIdleFunc(ScriptIdleFunc); + } + else + { + scr_running = 1; + AddIdleFunc(ScriptIdleFunc); + } +} + +void PlayScript(istream &scr) +{ + string word; + + scr_min_val = numeric_limits::infinity(); + scr_max_val = -scr_min_val; + + // read initializing commands + while (1) + { + scr >> ws; + if (!scr.good()) + { + cout << "Error in script" << endl; + return; + } + if (scr.peek() == '#') + { + getline(scr, word); + continue; + } + scr >> word; + if (word == "window") + { + scr >> window_x >> window_y >> window_w >> window_h; + } + else if (word == "data_coll_cycle") + { + scr >> dc_cycle; + } + else if (word == "data_coll_protocol") + { + scr >> dc_protocol; + } + else if (word == "solution") + { + if (ScriptReadSolution(scr, stream_state)) + { + return; + } + + // start the visualization + break; + } + else if (word == "quadrature") + { + if (ScriptReadQuadrature(scr, stream_state)) + { + return; + } + + // start the visualization + break; + } + else if (word == "psolution") + { + if (ScriptReadParSolution(scr, stream_state)) + { + return; + } + + // start the visualization + break; + } + else if (word == "pquadrature") + { + if (ScriptReadParQuadrature(scr, stream_state)) + { + return; + } + + // start the visualization + break; + } + else if (word == "mesh") + { + if (ScriptReadDisplMesh(scr, stream_state)) + { + return; + } + if (stream_state.mesh) + { + break; + } + } + else if (word == "data_coll_mesh") + { + if (ScriptReadDataColl(scr, stream_state)) + { + return; + } + + // start the visualization + break; + } + else if (word == "data_coll_field") + { + if (ScriptReadDataColl(scr, stream_state, false)) + { + return; + } + + // start the visualization + break; + } + else if (word == "data_coll_quad") + { + if (ScriptReadDataColl(scr, stream_state, false, true)) + { + return; + } + + // start the visualization + break; + } + else + { + cout << "Unknown command in script: " << word << endl; + } + } + + scr_level = scr_running = 0; + script = &scr; + stream_state.keys.clear(); + + // Make sure the singleton object returned by GetMainThread() is + // initialized from the main thread. + GetMainThread(); + + std::thread worker_thread + { + [&](DataState local_state) + { + // set the thread-local DataState + stream_state = std::move(local_state); + if (c_plot_caption != string_none) + { + plot_caption = c_plot_caption; + } + if (GLVisInitVis({})) + { + GetAppWindow()->setOnKeyDown(SDLK_SPACE, ScriptControl); + GLVisStartVis(); + } + }, + std::move(stream_state) + }; + + SDLMainLoop(); + worker_thread.join(); + + delete init_nodes; init_nodes = NULL; + + cout << "Script: min_val = " << scr_min_val + << ", max_val = " << scr_max_val << endl; + + script = NULL; +} diff --git a/lib/script_controller.hpp b/lib/script_controller.hpp new file mode 100644 index 00000000..b9ecf838 --- /dev/null +++ b/lib/script_controller.hpp @@ -0,0 +1,19 @@ +// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced +// at the Lawrence Livermore National Laboratory. All Rights reserved. See files +// LICENSE and NOTICE for details. LLNL-CODE-443271. +// +// This file is part of the GLVis visualization tool and library. For more +// information and source code availability see https://glvis.org. +// +// GLVis is free software; you can redistribute it and/or modify it under the +// terms of the BSD-3 license. We welcome feedback and contributions, see file +// CONTRIBUTING.md for details. + +#ifndef GLVIS_SCRIPT_CONTROLLER_HPP +#define GLVIS_SCRIPT_CONTROLLER_HPP + +#include + +void PlayScript(std::istream &scr); + +#endif // GLVIS_SCRIPT_CONTROLLER_HPP diff --git a/makefile b/makefile index 44fb9f92..80833500 100644 --- a/makefile +++ b/makefile @@ -255,10 +255,10 @@ ALL_SOURCE_FILES = \ lib/coll_reader.cpp lib/data_state.cpp lib/file_reader.cpp \ lib/font.cpp lib/gl2ps.c lib/gltf.cpp lib/material.cpp \ lib/openglvis.cpp lib/palettes_base.cpp lib/palettes.cpp lib/sdl.cpp \ - lib/sdl_helper.cpp lib/sdl_main.cpp lib/sdl_windows.cpp \ - lib/sdl_x11.cpp lib/stream_reader.cpp lib/threads.cpp lib/vsdata.cpp \ - lib/vssolution.cpp lib/vssolution3d.cpp lib/vsvector.cpp \ - lib/vsvector3d.cpp + lib/script_controller.cpp lib/sdl_helper.cpp lib/sdl_main.cpp \ + lib/sdl_windows.cpp lib/sdl_x11.cpp lib/stream_reader.cpp \ + lib/threads.cpp lib/vsdata.cpp lib/vssolution.cpp lib/vssolution3d.cpp \ + lib/vsvector.cpp lib/vsvector3d.cpp OBJC_SOURCE_FILES = $(if $(NOTMAC),,lib/sdl_mac.mm) DESKTOP_ONLY_SOURCE_FILES = \ lib/gl/renderer_ff.cpp lib/threads.cpp lib/gl2ps.c lib/sdl_x11.cpp @@ -276,11 +276,11 @@ HEADER_FILES = \ lib/data_state.hpp lib/file_reader.hpp lib/font.hpp \ lib/geom_utils.hpp lib/gl2ps.h lib/gltf.hpp lib/logo.hpp \ lib/material.hpp lib/openglvis.hpp lib/palettes_base.hpp \ - lib/palettes.hpp lib/sdl_helper.hpp lib/sdl.hpp lib/sdl_mac.hpp \ - lib/sdl_main.hpp lib/sdl_windows.hpp lib/sdl_x11.hpp \ - lib/stream_reader.hpp lib/threads.hpp lib/visual.hpp lib/vsdata.hpp \ - lib/vssolution.hpp lib/vssolution3d.hpp lib/vsvector.hpp \ - lib/vsvector3d.hpp + lib/palettes.hpp lib/script_controller.hpp lib/sdl_helper.hpp \ + lib/sdl.hpp lib/sdl_mac.hpp lib/sdl_main.hpp lib/sdl_windows.hpp \ + lib/sdl_x11.hpp lib/stream_reader.hpp lib/threads.hpp lib/visual.hpp \ + lib/vsdata.hpp lib/vssolution.hpp lib/vssolution3d.hpp \ + lib/vsvector.hpp lib/vsvector3d.hpp DESKTOP_SOURCE_FILES = $(COMMON_SOURCE_FILES) $(DESKTOP_ONLY_SOURCE_FILES) $(LOGO_FILE_CPP) WEB_SOURCE_FILES = $(COMMON_SOURCE_FILES) $(WEB_ONLY_SOURCE_FILES) From a7b9c58203e3de8e91c8f297e248db47ddafe17e Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Fri, 2 May 2025 14:03:44 -0700 Subject: [PATCH 03/65] Introduced Window structure. --- glvis.cpp | 142 +++++++++++++++++++------------------- lib/CMakeLists.txt | 3 +- lib/script_controller.cpp | 106 ++++++++++++++-------------- lib/threads.cpp | 2 +- lib/vsdata.cpp | 10 +-- lib/vsdata.hpp | 6 +- lib/vssolution.cpp | 4 +- lib/vsvector.cpp | 4 +- lib/vsvector3d.cpp | 2 +- lib/window.hpp | 29 ++++++++ makefile | 2 +- 11 files changed, 171 insertions(+), 139 deletions(-) create mode 100644 lib/window.hpp diff --git a/glvis.cpp b/glvis.cpp index f526fd02..5a1df8c1 100644 --- a/glvis.cpp +++ b/glvis.cpp @@ -34,6 +34,7 @@ #include "mfem.hpp" #include "lib/palettes.hpp" #include "lib/visual.hpp" +#include "lib/window.hpp" #include "lib/script_controller.hpp" #include "lib/stream_reader.hpp" #include "lib/file_reader.hpp" @@ -63,8 +64,6 @@ int window_w = 400; int window_h = 350; const char *window_title = string_default; const char *c_plot_caption = string_none; -thread_local string plot_caption; -thread_local string extra_caption; bool secure = socketstream::secure_default; // Global variables @@ -81,8 +80,8 @@ enum InputOptions INPUT_PARALLEL = 1 << 8, }; int input = INPUT_SERVER_MODE; -thread_local DataState stream_state; -thread_local VisualizationSceneScalarData *vs = NULL; + +thread_local Window win; extern thread_local GLVisCommand* glvis_command; thread_local communication_thread *comm_thread = NULL; @@ -101,7 +100,7 @@ void SwitchQuadSolution(); // Visualize the data in the global variables mesh, sol/grid_f, etc bool GLVisInitVis(StreamCollection input_streams) { - DataState::FieldType field_type = stream_state.GetType(); + DataState::FieldType field_type = win.data_state.GetType(); if (field_type <= DataState::FieldType::MIN || field_type >= DataState::FieldType::MAX) @@ -121,11 +120,11 @@ bool GLVisInitVis(StreamCollection input_streams) if (input_streams.size() > 0) { GetAppWindow()->setOnKeyDown(SDLK_SPACE, ThreadsPauseFunc); - glvis_command = new GLVisCommand(&vs, stream_state); + glvis_command = new GLVisCommand(&win.vs, win.data_state); comm_thread = new communication_thread(std::move(input_streams), glvis_command); } - if (stream_state.quad_f) + if (win.data_state.quad_f) { GetAppWindow()->setOnKeyDown('Q', SwitchQuadSolution); } @@ -134,49 +133,51 @@ bool GLVisInitVis(StreamCollection input_streams) if (field_type == DataState::FieldType::SCALAR || field_type == DataState::FieldType::MESH) { - if (stream_state.grid_f) + if (win.data_state.grid_f) { - stream_state.grid_f->GetNodalValues(stream_state.sol); + win.data_state.grid_f->GetNodalValues(win.data_state.sol); } - if (stream_state.mesh->SpaceDimension() == 2) + if (win.data_state.mesh->SpaceDimension() == 2) { VisualizationSceneSolution * vss; - if (stream_state.normals.Size() > 0) + if (win.data_state.normals.Size() > 0) { - vs = vss = new VisualizationSceneSolution(*stream_state.mesh, stream_state.sol, - stream_state.mesh_quad.get(), &stream_state.normals); + win.vs = vss = new VisualizationSceneSolution(*win.data_state.mesh, + win.data_state.sol, + win.data_state.mesh_quad.get(), &win.data_state.normals); } else { - vs = vss = new VisualizationSceneSolution(*stream_state.mesh, stream_state.sol, - stream_state.mesh_quad.get()); + win.vs = vss = new VisualizationSceneSolution(*win.data_state.mesh, + win.data_state.sol, + win.data_state.mesh_quad.get()); } - if (stream_state.grid_f) + if (win.data_state.grid_f) { - vss->SetGridFunction(*stream_state.grid_f); + vss->SetGridFunction(*win.data_state.grid_f); } if (field_type == DataState::FieldType::MESH) { - vs->OrthogonalProjection = 1; - vs->SetLight(false); - vs->Zoom(1.8); + win.vs->OrthogonalProjection = 1; + win.vs->SetLight(false); + win.vs->Zoom(1.8); // Use the 'bone' palette when visualizing a 2D mesh only (otherwise // the 'jet-like' palette is used in 2D, see vssolution.cpp). - vs->palette.SetIndex(4); + win.vs->palette.SetIndex(4); } } - else if (stream_state.mesh->SpaceDimension() == 3) + else if (win.data_state.mesh->SpaceDimension() == 3) { VisualizationSceneSolution3d * vss; - vs = vss = new VisualizationSceneSolution3d(*stream_state.mesh, - stream_state.sol, stream_state.mesh_quad.get()); - if (stream_state.grid_f) + win.vs = vss = new VisualizationSceneSolution3d(*win.data_state.mesh, + win.data_state.sol, win.data_state.mesh_quad.get()); + if (win.data_state.grid_f) { - vss->SetGridFunction(stream_state.grid_f.get()); + vss->SetGridFunction(win.data_state.grid_f.get()); } if (field_type == DataState::FieldType::MESH) { - if (stream_state.mesh->Dimension() == 3) + if (win.data_state.mesh->Dimension() == 3) { // Use the 'white' palette when visualizing a 3D volume mesh only vss->palette.SetIndex(11); @@ -194,68 +195,69 @@ bool GLVisInitVis(StreamCollection input_streams) } if (field_type == DataState::FieldType::MESH) { - if (stream_state.grid_f) + if (win.data_state.grid_f) { - mesh_range = stream_state.grid_f->Max() + 1.0; + mesh_range = win.data_state.grid_f->Max() + 1.0; } else { - mesh_range = stream_state.sol.Max() + 1.0; + mesh_range = win.data_state.sol.Max() + 1.0; } } } else if (field_type == DataState::FieldType::VECTOR) { - if (stream_state.mesh->SpaceDimension() == 2) + if (win.data_state.mesh->SpaceDimension() == 2) { - if (stream_state.grid_f) + if (win.data_state.grid_f) { - vs = new VisualizationSceneVector(*stream_state.grid_f); + win.vs = new VisualizationSceneVector(*win.data_state.grid_f); } else { - vs = new VisualizationSceneVector(*stream_state.mesh, stream_state.solu, - stream_state.solv, stream_state.mesh_quad.get()); + win.vs = new VisualizationSceneVector(*win.data_state.mesh, win.data_state.solu, + win.data_state.solv, win.data_state.mesh_quad.get()); } } - else if (stream_state.mesh->SpaceDimension() == 3) + else if (win.data_state.mesh->SpaceDimension() == 3) { - if (stream_state.grid_f) + if (win.data_state.grid_f) { - stream_state.ProjectVectorFEGridFunction(); - vs = new VisualizationSceneVector3d(*stream_state.grid_f, - stream_state.mesh_quad.get()); + win.data_state.ProjectVectorFEGridFunction(); + win.vs = new VisualizationSceneVector3d(*win.data_state.grid_f, + win.data_state.mesh_quad.get()); } else { - vs = new VisualizationSceneVector3d(*stream_state.mesh, stream_state.solu, - stream_state.solv, stream_state.solw, - stream_state.mesh_quad.get()); + win.vs = new VisualizationSceneVector3d(*win.data_state.mesh, + win.data_state.solu, + win.data_state.solv, win.data_state.solw, + win.data_state.mesh_quad.get()); } } } - if (vs) + if (win.vs) { // increase the refinement factors if visualizing a GridFunction - if (stream_state.grid_f) + if (win.data_state.grid_f) { - vs->AutoRefine(); - vs->SetShading(VisualizationSceneScalarData::Shading::Noncomforming, true); + win.vs->AutoRefine(); + win.vs->SetShading(VisualizationSceneScalarData::Shading::Noncomforming, true); } if (mesh_range > 0.0) { - vs->SetValueRange(-mesh_range, mesh_range); - vs->SetAutoscale(0); + win.vs->SetValueRange(-mesh_range, mesh_range); + win.vs->SetAutoscale(0); } - if (stream_state.mesh->SpaceDimension() == 2 + if (win.data_state.mesh->SpaceDimension() == 2 && field_type == DataState::FieldType::MESH) { - SetVisualizationScene(vs, 2, stream_state.keys.c_str()); + SetVisualizationScene(win.vs, 2, win.data_state.keys.c_str()); } else { - SetVisualizationScene(vs, 3, stream_state.keys.c_str()); + SetVisualizationScene(win.vs, 3, win.data_state.keys.c_str()); } } return true; @@ -263,8 +265,8 @@ bool GLVisInitVis(StreamCollection input_streams) void GLVisStartVis() { - RunVisualization(); // deletes vs - vs = NULL; + RunVisualization(); // deletes win.vs + win.vs = NULL; if (glvis_command) { glvis_command->Terminate(); @@ -306,10 +308,10 @@ class Session auto funcThread = [](DataState thread_state, StreamCollection is) { // Set thread-local stream state - stream_state = std::move(thread_state); + win.data_state = std::move(thread_state); if (c_plot_caption != string_none) { - plot_caption = c_plot_caption; + win.plot_caption = c_plot_caption; } if (GLVisInitVis(std::move(is))) @@ -628,17 +630,17 @@ int main (int argc, char *argv[]) "Palette file."); args.AddOption(&arg_keys, "-k", "--keys", "Execute key shortcut commands in the GLVis window."); - args.AddOption(&stream_state.fix_elem_orient, "-fo", "--fix-orientations", + args.AddOption(&win.data_state.fix_elem_orient, "-fo", "--fix-orientations", "-no-fo", "--dont-fix-orientations", "Attempt to fix the orientations of inverted elements."); - args.AddOption(&stream_state.keep_attr, "-a", "--real-attributes", + args.AddOption(&win.data_state.keep_attr, "-a", "--real-attributes", "-ap", "--processor-attributes", "When opening a parallel mesh, use the real mesh attributes" " or replace them with the processor rank."); args.AddOption(&geom_ref_type, "-grt", "--geometry-refiner-type", "Set of points to use when refining geometry:" " 3 = uniform, 1 = Gauss-Lobatto, (see mfem::Quadrature1D)."); - args.AddOption(&stream_state.save_coloring, "-sc", "--save-coloring", + args.AddOption(&win.data_state.save_coloring, "-sc", "--save-coloring", "-no-sc", "--dont-save-coloring", "Save the mesh coloring generated when opening only a mesh."); args.AddOption(&portnum, "-p", "--listen-port", @@ -749,7 +751,7 @@ int main (int argc, char *argv[]) } if (arg_keys != string_none) { - stream_state.keys = arg_keys; + win.data_state.keys = arg_keys; } if (font_name != string_default) { @@ -769,7 +771,7 @@ int main (int argc, char *argv[]) } if (c_plot_caption != string_none) { - plot_caption = c_plot_caption; + win.plot_caption = c_plot_caption; } if (legacy_gl_ctx == true) { @@ -794,8 +796,8 @@ int main (int argc, char *argv[]) // initialized from the main thread. GetMainThread(); - Session stream_session(stream_state.fix_elem_orient, - stream_state.save_coloring); + Session stream_session(win.data_state.fix_elem_orient, + win.data_state.save_coloring); if (!stream_session.StartSavedSession(stream_file)) { @@ -862,8 +864,8 @@ int main (int argc, char *argv[]) // Run server in new thread std::thread serverThread{GLVisServer, portnum, save_stream, - stream_state.fix_elem_orient, - stream_state.save_coloring}; + win.data_state.fix_elem_orient, + win.data_state.save_coloring}; // Start SDL in main thread SDLMainLoop(true); @@ -904,7 +906,7 @@ int main (int argc, char *argv[]) return 1; } - FileReader reader(stream_state, pad_digits); + FileReader reader(win.data_state, pad_digits); int ierr; if (input & INPUT_PARALLEL) { @@ -953,7 +955,7 @@ int main (int argc, char *argv[]) mesh_only = true; } - DataCollectionReader reader(stream_state); + DataCollectionReader reader(win.data_state); reader.SetPadDigits(pad_digits); if (dc_protocol != string_default) { @@ -977,7 +979,7 @@ int main (int argc, char *argv[]) // initialized from the main thread. GetMainThread(); - Session single_session(std::move(stream_state)); + Session single_session(std::move(win.data_state)); single_session.StartSession(); SDLMainLoop(); @@ -1009,8 +1011,8 @@ void PrintSampleUsage(ostream &os) void SwitchQuadSolution() { - int iqs = ((int)stream_state.GetQuadSolution()+1) + int iqs = ((int)win.data_state.GetQuadSolution()+1) % ((int)DataState::QuadSolution::MAX); - stream_state.SwitchQuadSolution((DataState::QuadSolution)iqs, vs); + win.data_state.SwitchQuadSolution((DataState::QuadSolution)iqs, win.vs); SendExposeEvent(); } diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 5654f430..89d963d5 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -65,7 +65,8 @@ list(APPEND HEADERS vssolution.hpp vssolution3d.hpp vsvector.hpp - vsvector3d.hpp) + vsvector3d.hpp + window.hpp) if(EMSCRIPTEN) # Emscripten build target diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index 55b166ea..4337593c 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -9,6 +9,7 @@ // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. +#include "window.hpp" #include "file_reader.hpp" #include "coll_reader.hpp" #include "stream_reader.hpp" @@ -28,8 +29,7 @@ extern int window_w; extern int window_h; extern const char *c_plot_caption; -extern thread_local DataState stream_state; -extern thread_local VisualizationSceneScalarData *vs; +extern thread_local Window win; istream *script = NULL; int scr_running = 0; @@ -378,7 +378,7 @@ void ExecuteScriptCommand() } } - if (stream_state.SetNewMeshAndSolution(std::move(new_state), vs)) + if (win.data_state.SetNewMeshAndSolution(std::move(new_state), win.vs)) { MyExpose(); } @@ -401,20 +401,20 @@ void ExecuteScriptCommand() } cout << "-> " << word << endl; - if (scr_min_val > vs->GetMinV()) + if (scr_min_val > win.vs->GetMinV()) { - scr_min_val = vs->GetMinV(); + scr_min_val = win.vs->GetMinV(); } - if (scr_max_val < vs->GetMaxV()) + if (scr_max_val < win.vs->GetMaxV()) { - scr_max_val = vs->GetMaxV(); + scr_max_val = win.vs->GetMaxV(); } } else if (word == "viewcenter") { - scr >> vs->ViewCenterX >> vs->ViewCenterY; + scr >> win.vs->ViewCenterX >> win.vs->ViewCenterY; cout << "Script: viewcenter: " - << vs->ViewCenterX << ' ' << vs->ViewCenterY << endl; + << win.vs->ViewCenterX << ' ' << win.vs->ViewCenterY << endl; MyExpose(); } else if (word == "perspective") @@ -423,11 +423,11 @@ void ExecuteScriptCommand() cout << "Script: perspective: " << word; if (word == "off") { - vs->OrthogonalProjection = 1; + win.vs->OrthogonalProjection = 1; } else if (word == "on") { - vs->OrthogonalProjection = 0; + win.vs->OrthogonalProjection = 0; } else { @@ -442,11 +442,11 @@ void ExecuteScriptCommand() cout << "Script: light: " << word; if (word == "off") { - vs->SetLight(false); + win.vs->SetLight(false); } else if (word == "on") { - vs->SetLight(true); + win.vs->SetLight(true); } else { @@ -460,7 +460,7 @@ void ExecuteScriptCommand() double theta, phi; scr >> theta >> phi; cout << "Script: view: " << theta << ' ' << phi << endl; - vs->SetView(theta, phi); + win.vs->SetView(theta, phi); MyExpose(); } else if (word == "zoom") @@ -468,7 +468,7 @@ void ExecuteScriptCommand() double factor; scr >> factor; cout << "Script: zoom: " << factor << endl; - vs->Zoom(factor); + win.vs->Zoom(factor); MyExpose(); } else if (word == "shading") @@ -491,7 +491,7 @@ void ExecuteScriptCommand() } if (s != VisualizationSceneScalarData::Shading::Invalid) { - vs->SetShading(s, false); + win.vs->SetShading(s, false); cout << word << endl; MyExpose(); } @@ -505,7 +505,7 @@ void ExecuteScriptCommand() int t, b; scr >> t >> b; cout << "Script: subdivisions: " << flush; - vs->SetRefineFactors(t, b); + win.vs->SetRefineFactors(t, b); cout << t << ' ' << b << endl; MyExpose(); } @@ -514,7 +514,7 @@ void ExecuteScriptCommand() double min, max; scr >> min >> max; cout << "Script: valuerange: " << flush; - vs->SetValueRange(min, max); + win.vs->SetValueRange(min, max); cout << min << ' ' << max << endl; MyExpose(); } @@ -524,19 +524,19 @@ void ExecuteScriptCommand() cout << "Script: autoscale: " << word; if (word == "off") { - vs->SetAutoscale(0); + win.vs->SetAutoscale(0); } else if (word == "on") { - vs->SetAutoscale(1); + win.vs->SetAutoscale(1); } else if (word == "value") { - vs->SetAutoscale(2); + win.vs->SetAutoscale(2); } else if (word == "mesh") { - vs->SetAutoscale(3); + win.vs->SetAutoscale(3); } else { @@ -550,8 +550,8 @@ void ExecuteScriptCommand() int num; scr >> min >> max >> num; cout << "Script: levellines: " << flush; - vs->SetLevelLines(min, max, num); - vs->UpdateLevelLines(); + win.vs->SetLevelLines(min, max, num); + win.vs->UpdateLevelLines(); cout << min << ' ' << max << ' ' << num << endl; MyExpose(); } @@ -562,7 +562,7 @@ void ExecuteScriptCommand() scr >> ws >> delim; getline(scr, axis_formatting, delim); cout << "Script: axis_numberformat: " << flush; - vs->SetAxisNumberFormat(axis_formatting); + win.vs->SetAxisNumberFormat(axis_formatting); cout << axis_formatting << endl; MyExpose(); } @@ -573,7 +573,7 @@ void ExecuteScriptCommand() scr >> ws >> delim; getline(scr, colorbar_formatting, delim); cout << "Script: colorbar_numberformat: " << flush; - vs->SetColorbarNumberFormat(colorbar_formatting); + win.vs->SetColorbarNumberFormat(colorbar_formatting); cout << colorbar_formatting << endl; MyExpose(); } @@ -587,10 +587,10 @@ void ExecuteScriptCommand() } else if (word == "keys") { - scr >> stream_state.keys; - cout << "Script: keys: '" << stream_state.keys << "'" << endl; + scr >> win.data_state.keys; + cout << "Script: keys: '" << win.data_state.keys << "'" << endl; // SendKeySequence(keys.c_str()); - CallKeySequence(stream_state.keys.c_str()); + CallKeySequence(win.data_state.keys.c_str()); MyExpose(); } else if (word == "palette") @@ -598,7 +598,7 @@ void ExecuteScriptCommand() int pal; scr >> pal; cout << "Script: palette: " << pal << endl; - vs->palette.SetIndex(pal-1); + win.vs->palette.SetIndex(pal-1); MyExpose(); } else if (word == "palette_repeat") @@ -606,8 +606,8 @@ void ExecuteScriptCommand() int rpt_times; scr >> rpt_times; cout << "Script: palette_repeat: " << rpt_times << endl; - vs->palette.SetRepeatTimes(rpt_times); - vs->palette.GenerateTextures(); + win.vs->palette.SetRepeatTimes(rpt_times); + win.vs->palette.GenerateTextures(); MyExpose(); } else if (word == "toggle_attributes") @@ -629,7 +629,7 @@ void ExecuteScriptCommand() } scr.get(); // read the end symbol: ';' cout << endl; - vs->ToggleAttributes(attr_list); + win.vs->ToggleAttributes(attr_list); MyExpose(); } else if (word == "rotmat") @@ -637,8 +637,8 @@ void ExecuteScriptCommand() cout << "Script: rotmat:"; for (int i = 0; i < 16; i++) { - scr >> vs->rotmat[i/4][i%4]; - cout << ' ' << vs->rotmat[i/4][i%4]; + scr >> win.vs->rotmat[i/4][i%4]; + cout << ' ' << win.vs->rotmat[i/4][i%4]; } cout << endl; MyExpose(); @@ -653,7 +653,7 @@ void ExecuteScriptCommand() cout << ' ' << cam[i]; } cout << endl; - vs->cam.Set(cam); + win.vs->cam.Set(cam); MyExpose(); } else if (word == "scale") @@ -663,7 +663,7 @@ void ExecuteScriptCommand() scr >> scale; cout << ' ' << scale; cout << endl; - vs->Scale(scale); + win.vs->Scale(scale); MyExpose(); } else if (word == "translate") @@ -673,15 +673,15 @@ void ExecuteScriptCommand() scr >> x >> y >> z; cout << ' ' << x << ' ' << y << ' ' << z; cout << endl; - vs->Translate(x, y, z); + win.vs->Translate(x, y, z); MyExpose(); } else if (word == "plot_caption") { char delim; scr >> ws >> delim; - getline(scr, plot_caption, delim); - vs->PrepareCaption(); // turn on or off the caption + getline(scr, win.plot_caption, delim); + win.vs->PrepareCaption(); // turn on or off the caption MyExpose(); } else @@ -754,7 +754,7 @@ void PlayScript(istream &scr) } else if (word == "solution") { - if (ScriptReadSolution(scr, stream_state)) + if (ScriptReadSolution(scr, win.data_state)) { return; } @@ -764,7 +764,7 @@ void PlayScript(istream &scr) } else if (word == "quadrature") { - if (ScriptReadQuadrature(scr, stream_state)) + if (ScriptReadQuadrature(scr, win.data_state)) { return; } @@ -774,7 +774,7 @@ void PlayScript(istream &scr) } else if (word == "psolution") { - if (ScriptReadParSolution(scr, stream_state)) + if (ScriptReadParSolution(scr, win.data_state)) { return; } @@ -784,7 +784,7 @@ void PlayScript(istream &scr) } else if (word == "pquadrature") { - if (ScriptReadParQuadrature(scr, stream_state)) + if (ScriptReadParQuadrature(scr, win.data_state)) { return; } @@ -794,18 +794,18 @@ void PlayScript(istream &scr) } else if (word == "mesh") { - if (ScriptReadDisplMesh(scr, stream_state)) + if (ScriptReadDisplMesh(scr, win.data_state)) { return; } - if (stream_state.mesh) + if (win.data_state.mesh) { break; } } else if (word == "data_coll_mesh") { - if (ScriptReadDataColl(scr, stream_state)) + if (ScriptReadDataColl(scr, win.data_state)) { return; } @@ -815,7 +815,7 @@ void PlayScript(istream &scr) } else if (word == "data_coll_field") { - if (ScriptReadDataColl(scr, stream_state, false)) + if (ScriptReadDataColl(scr, win.data_state, false)) { return; } @@ -825,7 +825,7 @@ void PlayScript(istream &scr) } else if (word == "data_coll_quad") { - if (ScriptReadDataColl(scr, stream_state, false, true)) + if (ScriptReadDataColl(scr, win.data_state, false, true)) { return; } @@ -841,7 +841,7 @@ void PlayScript(istream &scr) scr_level = scr_running = 0; script = &scr; - stream_state.keys.clear(); + win.data_state.keys.clear(); // Make sure the singleton object returned by GetMainThread() is // initialized from the main thread. @@ -852,10 +852,10 @@ void PlayScript(istream &scr) [&](DataState local_state) { // set the thread-local DataState - stream_state = std::move(local_state); + win.data_state = std::move(local_state); if (c_plot_caption != string_none) { - plot_caption = c_plot_caption; + win.plot_caption = c_plot_caption; } if (GLVisInitVis({})) { @@ -863,7 +863,7 @@ void PlayScript(istream &scr) GLVisStartVis(); } }, - std::move(stream_state) + std::move(win.data_state) }; SDLMainLoop(); diff --git a/lib/threads.cpp b/lib/threads.cpp index 5c2cb678..9e547d3b 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -539,7 +539,7 @@ int GLVisCommand::Execute() case PLOT_CAPTION: { cout << "Command: plot_caption: " << plot_caption << endl; - ::plot_caption = plot_caption; + win.plot_caption = plot_caption; (*vs)->PrepareCaption(); // turn on or off the caption MyExpose(); break; diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index dd19091b..17884eb9 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -596,13 +596,13 @@ void VisualizationSceneScalarData::PrepareColorBar (double minval, // Draw a centered caption at the top (visible with the colorbar) void VisualizationSceneScalarData::PrepareCaption() { - bool empty = plot_caption.empty(); + bool empty = win.plot_caption.empty(); colorbar = (colorbar ? empty+1 : !empty); - string caption(plot_caption); - if (!extra_caption.empty()) + string caption(win.plot_caption); + if (!win.extra_caption.empty()) { - caption += " (" + extra_caption + ")"; + caption += " (" + win.extra_caption + ")"; } caption_buf.clear(); @@ -643,7 +643,7 @@ void KeycPressed(GLenum state) void KeyCPressed() { cout << "Enter new caption: " << flush; - std::getline(cin, plot_caption); + std::getline(cin, win.plot_caption); vsdata->PrepareCaption(); // turn on or off the caption SendExposeEvent(); } diff --git a/lib/vsdata.hpp b/lib/vsdata.hpp index ed09eca6..60b61fe5 100644 --- a/lib/vsdata.hpp +++ b/lib/vsdata.hpp @@ -17,11 +17,11 @@ #include "mfem.hpp" #include "openglvis.hpp" #include "aux_vis.hpp" +#include "window.hpp" using namespace mfem; -extern thread_local std::string plot_caption; // defined in glvis.cpp -extern thread_local std::string extra_caption; // defined in glvis.cpp +extern thread_local Window win; // defined in glvis.cpp class Plane { @@ -272,7 +272,7 @@ class VisualizationSceneScalarData : public VisualizationScene // colorbar states are: 0) no colorbar, no caption; 1) colorbar with // caption; 2) colorbar without caption. static const int next[2][3] = { { 1, 2, 0 }, { 2, 0, 0 } }; - colorbar = next[plot_caption.empty()][colorbar]; + colorbar = next[win.plot_caption.empty()][colorbar]; } // Turn on or off the caption diff --git a/lib/vssolution.cpp b/lib/vssolution.cpp index 246f88c0..0033e512 100644 --- a/lib/vssolution.cpp +++ b/lib/vssolution.cpp @@ -549,11 +549,11 @@ void VisualizationSceneSolution::ToggleDrawElems() if (drawelems < 2) { - extra_caption.clear(); + win.extra_caption.clear(); } else { - extra_caption = modes[drawelems]; + win.extra_caption = modes[drawelems]; } if (drawelems == 0) diff --git a/lib/vsvector.cpp b/lib/vsvector.cpp index 2b5efda4..926e9c8a 100644 --- a/lib/vsvector.cpp +++ b/lib/vsvector.cpp @@ -381,7 +381,7 @@ void VisualizationSceneVector::CycleVec2Scalar(int print) } Vec2Scalar = Vec2ScalarFunctions[i]; - extra_caption = Vec2ScalarNames[i]; + win.extra_caption = Vec2ScalarNames[i]; for (i = 0; i < mesh->GetNV(); i++) { @@ -488,7 +488,7 @@ void VisualizationSceneVector::Init() ArrowScale = 1.0; RefineFactor = 1; Vec2Scalar = VecLength; - extra_caption = Vec2ScalarNames[0]; + win.extra_caption = Vec2ScalarNames[0]; for (int i = 0; i < mesh->GetNV(); i++) { diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index d66059f2..308eb8b4 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -330,7 +330,7 @@ void VisualizationSceneVector3d::SetScalarFunction() } break; } - extra_caption = scal_func_name[scal_func]; + win.extra_caption = scal_func_name[scal_func]; } void VisualizationSceneVector3d::ToggleScalarFunction() diff --git a/lib/window.hpp b/lib/window.hpp new file mode 100644 index 00000000..8f880177 --- /dev/null +++ b/lib/window.hpp @@ -0,0 +1,29 @@ +// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced +// at the Lawrence Livermore National Laboratory. All Rights reserved. See files +// LICENSE and NOTICE for details. LLNL-CODE-443271. +// +// This file is part of the GLVis visualization tool and library. For more +// information and source code availability see https://glvis.org. +// +// GLVis is free software; you can redistribute it and/or modify it under the +// terms of the BSD-3 license. We welcome feedback and contributions, see file +// CONTRIBUTING.md for details. + +#ifndef GLVIS_WINDOW_HPP +#define GLVIS_WINDOW_HPP + +#include + +#include "data_state.hpp" + +class VisualizationSceneScalarData; + +struct Window +{ + DataState data_state; + VisualizationSceneScalarData *vs = NULL; + std::string plot_caption; + std::string extra_caption; +}; + +#endif // GLVIS_WINDOW_HPP diff --git a/makefile b/makefile index 80833500..5f7f538b 100644 --- a/makefile +++ b/makefile @@ -280,7 +280,7 @@ HEADER_FILES = \ lib/sdl.hpp lib/sdl_mac.hpp lib/sdl_main.hpp lib/sdl_windows.hpp \ lib/sdl_x11.hpp lib/stream_reader.hpp lib/threads.hpp lib/visual.hpp \ lib/vsdata.hpp lib/vssolution.hpp lib/vssolution3d.hpp \ - lib/vsvector.hpp lib/vsvector3d.hpp + lib/vsvector.hpp lib/vsvector3d.hpp lib/window.hpp DESKTOP_SOURCE_FILES = $(COMMON_SOURCE_FILES) $(DESKTOP_ONLY_SOURCE_FILES) $(LOGO_FILE_CPP) WEB_SOURCE_FILES = $(COMMON_SOURCE_FILES) $(WEB_ONLY_SOURCE_FILES) From 8b9a8b7c5035dc54a06120c352ff685783b7597d Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Fri, 2 May 2025 17:01:39 -0700 Subject: [PATCH 04/65] Removed shared Window structure from visualization scenes. --- glvis.cpp | 51 +++++-------------------------- lib/threads.cpp | 60 ++++++++++++++++++------------------ lib/threads.hpp | 15 ++++----- lib/vsdata.cpp | 20 +++++++----- lib/vsdata.hpp | 10 +++--- lib/vssolution.cpp | 24 ++++++++------- lib/vssolution.hpp | 6 ++-- lib/vssolution3d.cpp | 22 +++++++------- lib/vssolution3d.hpp | 5 ++- lib/vsvector.cpp | 72 ++++++++++++++++++++------------------------ lib/vsvector.hpp | 5 ++- lib/vsvector3d.cpp | 59 +++++++++++++++--------------------- lib/vsvector3d.hpp | 8 ++--- 13 files changed, 149 insertions(+), 208 deletions(-) diff --git a/glvis.cpp b/glvis.cpp index 5a1df8c1..29c019e2 100644 --- a/glvis.cpp +++ b/glvis.cpp @@ -120,7 +120,7 @@ bool GLVisInitVis(StreamCollection input_streams) if (input_streams.size() > 0) { GetAppWindow()->setOnKeyDown(SDLK_SPACE, ThreadsPauseFunc); - glvis_command = new GLVisCommand(&win.vs, win.data_state); + glvis_command = new GLVisCommand(win); comm_thread = new communication_thread(std::move(input_streams), glvis_command); } @@ -139,23 +139,8 @@ bool GLVisInitVis(StreamCollection input_streams) } if (win.data_state.mesh->SpaceDimension() == 2) { - VisualizationSceneSolution * vss; - if (win.data_state.normals.Size() > 0) - { - win.vs = vss = new VisualizationSceneSolution(*win.data_state.mesh, - win.data_state.sol, - win.data_state.mesh_quad.get(), &win.data_state.normals); - } - else - { - win.vs = vss = new VisualizationSceneSolution(*win.data_state.mesh, - win.data_state.sol, - win.data_state.mesh_quad.get()); - } - if (win.data_state.grid_f) - { - vss->SetGridFunction(*win.data_state.grid_f); - } + win.vs = new VisualizationSceneSolution(win); + if (field_type == DataState::FieldType::MESH) { win.vs->OrthogonalProjection = 1; @@ -168,13 +153,9 @@ bool GLVisInitVis(StreamCollection input_streams) } else if (win.data_state.mesh->SpaceDimension() == 3) { - VisualizationSceneSolution3d * vss; - win.vs = vss = new VisualizationSceneSolution3d(*win.data_state.mesh, - win.data_state.sol, win.data_state.mesh_quad.get()); - if (win.data_state.grid_f) - { - vss->SetGridFunction(win.data_state.grid_f.get()); - } + VisualizationSceneSolution3d *vss; + win.vs = vss = new VisualizationSceneSolution3d(win); + if (field_type == DataState::FieldType::MESH) { if (win.data_state.mesh->Dimension() == 3) @@ -209,31 +190,15 @@ bool GLVisInitVis(StreamCollection input_streams) { if (win.data_state.mesh->SpaceDimension() == 2) { - if (win.data_state.grid_f) - { - win.vs = new VisualizationSceneVector(*win.data_state.grid_f); - } - else - { - win.vs = new VisualizationSceneVector(*win.data_state.mesh, win.data_state.solu, - win.data_state.solv, win.data_state.mesh_quad.get()); - } + win.vs = new VisualizationSceneVector(win); } else if (win.data_state.mesh->SpaceDimension() == 3) { if (win.data_state.grid_f) { win.data_state.ProjectVectorFEGridFunction(); - win.vs = new VisualizationSceneVector3d(*win.data_state.grid_f, - win.data_state.mesh_quad.get()); - } - else - { - win.vs = new VisualizationSceneVector3d(*win.data_state.mesh, - win.data_state.solu, - win.data_state.solv, win.data_state.solw, - win.data_state.mesh_quad.get()); } + win.vs = new VisualizationSceneVector3d(win); } } diff --git a/lib/threads.cpp b/lib/threads.cpp index 9e547d3b..08107e3a 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -18,11 +18,9 @@ using namespace std; extern const char *strings_off_on[]; // defined in vsdata.cpp -GLVisCommand::GLVisCommand( - VisualizationSceneScalarData **_vs, DataState& state) - : curr_state(state) +GLVisCommand::GLVisCommand(Window &win_) + : win(win_) { - vs = _vs; // should be set in this thread by a call to InitVisualization() thread_wnd = GetAppWindow(); @@ -463,7 +461,7 @@ int GLVisCommand::Execute() } else { - auto qs = curr_state.GetQuadSolution(); + auto qs = win.data_state.GetQuadSolution(); if (qs != DataState::QuadSolution::NONE) { new_state.SetQuadSolution(qs); @@ -475,11 +473,11 @@ int GLVisCommand::Execute() new_state.ExtrudeMeshAndSolution(); } } - if (curr_state.SetNewMeshAndSolution(std::move(new_state), *vs)) + if (win.data_state.SetNewMeshAndSolution(std::move(new_state), win.vs)) { if (mesh_range > 0.0) { - (*vs)->SetValueRange(-mesh_range, mesh_range); + win.vs->SetValueRange(-mesh_range, mesh_range); } MyExpose(); } @@ -540,7 +538,7 @@ int GLVisCommand::Execute() { cout << "Command: plot_caption: " << plot_caption << endl; win.plot_caption = plot_caption; - (*vs)->PrepareCaption(); // turn on or off the caption + win.vs->PrepareCaption(); // turn on or off the caption MyExpose(); break; } @@ -549,8 +547,8 @@ int GLVisCommand::Execute() { cout << "Command: axis_labels: '" << axis_label_x << "' '" << axis_label_y << "' '" << axis_label_z << "'" << endl; - (*vs)->SetAxisLabels(axis_label_x.c_str(), axis_label_y.c_str(), - axis_label_z.c_str()); + win.vs->SetAxisLabels(axis_label_x.c_str(), axis_label_y.c_str(), + axis_label_z.c_str()); MyExpose(); break; } @@ -559,7 +557,7 @@ int GLVisCommand::Execute() { cout << "Command: axis_numberformat: '" << axis_formatting << "'" << endl; - (*vs)->SetAxisNumberFormat(axis_formatting); + win.vs->SetAxisNumberFormat(axis_formatting); MyExpose(); break; } @@ -568,7 +566,7 @@ int GLVisCommand::Execute() { cout << "Command: colorbar_numberformat: '" << colorbar_formatting << "'" << endl; - (*vs)->SetColorbarNumberFormat(colorbar_formatting); + win.vs->SetColorbarNumberFormat(colorbar_formatting); MyExpose(); break; } @@ -584,7 +582,7 @@ int GLVisCommand::Execute() { cout << "Command: view: " << view_ang_theta << ' ' << view_ang_phi << endl; - (*vs)->SetView(view_ang_theta, view_ang_phi); + win.vs->SetView(view_ang_theta, view_ang_phi); MyExpose(); break; } @@ -592,7 +590,7 @@ int GLVisCommand::Execute() case ZOOM: { cout << "Command: zoom: " << zoom_factor << endl; - (*vs)->Zoom(zoom_factor); + win.vs->Zoom(zoom_factor); MyExpose(); break; } @@ -600,7 +598,7 @@ int GLVisCommand::Execute() case SUBDIVISIONS: { cout << "Command: subdivisions: " << flush; - (*vs)->SetRefineFactors(subdiv_tot, subdiv_bdr); + win.vs->SetRefineFactors(subdiv_tot, subdiv_bdr); cout << subdiv_tot << ' ' << subdiv_bdr << endl; MyExpose(); break; @@ -609,7 +607,7 @@ int GLVisCommand::Execute() case VALUE_RANGE: { cout << "Command: valuerange: " << flush; - (*vs)->SetValueRange(val_min, val_max); + win.vs->SetValueRange(val_min, val_max); cout << val_min << ' ' << val_max << endl; MyExpose(); break; @@ -618,8 +616,8 @@ int GLVisCommand::Execute() case LEVELLINES: { cout << "Command: levellines: " << flush; - (*vs)->SetLevelLines(lvl_min, lvl_max, lvl_num); - (*vs)->UpdateLevelLines(); + win.vs->SetLevelLines(lvl_min, lvl_max, lvl_num); + win.vs->UpdateLevelLines(); cout << lvl_min << ' ' << lvl_max << ' ' << lvl_num << endl; MyExpose(); break; @@ -644,7 +642,7 @@ int GLVisCommand::Execute() } if (s != VisualizationSceneScalarData::Shading::Invalid) { - (*vs)->SetShading(s, false); + win.vs->SetShading(s, false); cout << shading << endl; MyExpose(); } @@ -659,8 +657,8 @@ int GLVisCommand::Execute() { cout << "Command: viewcenter: " << view_center_x << ' ' << view_center_y << endl; - (*vs)->ViewCenterX = view_center_x; - (*vs)->ViewCenterY = view_center_y; + win.vs->ViewCenterX = view_center_x; + win.vs->ViewCenterY = view_center_y; MyExpose(); break; } @@ -670,19 +668,19 @@ int GLVisCommand::Execute() cout << "Command: autoscale: " << autoscale_mode; if (autoscale_mode == "off") { - (*vs)->SetAutoscale(0); + win.vs->SetAutoscale(0); } else if (autoscale_mode == "on") { - (*vs)->SetAutoscale(1); + win.vs->SetAutoscale(1); } else if (autoscale_mode == "value") { - (*vs)->SetAutoscale(2); + win.vs->SetAutoscale(2); } else if (autoscale_mode == "mesh") { - (*vs)->SetAutoscale(3); + win.vs->SetAutoscale(3); } else { @@ -695,10 +693,10 @@ int GLVisCommand::Execute() case PALETTE: { cout << "Command: palette: " << palette << endl; - (*vs)->palette.SetIndex(palette-1); + win.vs->palette.SetIndex(palette-1); if (!GetUseTexture()) { - (*vs)->EventUpdateColors(); + win.vs->EventUpdateColors(); } MyExpose(); break; @@ -707,12 +705,12 @@ int GLVisCommand::Execute() case PALETTE_REPEAT: { cout << "Command: palette_repeat: " << palette_repeat << endl; - (*vs)->palette.SetRepeatTimes(palette_repeat); - (*vs)->palette.GenerateTextures(); + win.vs->palette.SetRepeatTimes(palette_repeat); + win.vs->palette.GenerateTextures(); if (!GetUseTexture()) { - (*vs)->EventUpdateColors(); + win.vs->EventUpdateColors(); } MyExpose(); break; @@ -726,7 +724,7 @@ int GLVisCommand::Execute() cout << ' ' << camera[i]; } cout << endl; - (*vs)->cam.Set(camera); + win.vs->cam.Set(camera); MyExpose(); break; } diff --git a/lib/threads.hpp b/lib/threads.hpp index 1a48aa95..78c1649d 100644 --- a/lib/threads.hpp +++ b/lib/threads.hpp @@ -12,8 +12,7 @@ #ifndef GLVIS_THREADS_HPP #define GLVIS_THREADS_HPP -#include "vsdata.hpp" -#include "data_state.hpp" +#include "window.hpp" #include #include #include @@ -23,9 +22,8 @@ class GLVisCommand { private: // Pointers to global GLVis data - VisualizationSceneScalarData **vs; - DataState& curr_state; - SdlWindow *thread_wnd; + Window &win; + SdlWindow *thread_wnd; std::mutex glvis_mutex; std::condition_variable glvis_cond; @@ -101,12 +99,11 @@ class GLVisCommand public: // called by the main execution thread - GLVisCommand(VisualizationSceneScalarData **_vs, - DataState& thread_state); + GLVisCommand(Window &win); // to be used by worker threads - bool KeepAttrib() { return curr_state.keep_attr; } // may need to sync this - bool FixElementOrientations() { return curr_state.fix_elem_orient; } + bool KeepAttrib() { return win.data_state.keep_attr; } // may need to sync this + bool FixElementOrientations() { return win.data_state.fix_elem_orient; } // called by worker threads int NewMeshAndSolution(DataState &&ss); diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index 17884eb9..fdd1ffc0 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -611,7 +611,8 @@ void VisualizationSceneScalarData::PrepareCaption() GetFont()->getObjectSize(caption, caption_w, caption_h); } -thread_local VisualizationSceneScalarData * vsdata; +static thread_local VisualizationSceneScalarData * vsdata; +static thread_local Window *window; extern thread_local VisualizationScene * locscene; void KeycPressed(GLenum state) @@ -643,7 +644,7 @@ void KeycPressed(GLenum state) void KeyCPressed() { cout << "Enter new caption: " << flush; - std::getline(cin, win.plot_caption); + std::getline(cin, window->plot_caption); vsdata->PrepareCaption(); // turn on or off the caption SendExposeEvent(); } @@ -1354,19 +1355,22 @@ void VisualizationSceneScalarData::SetAutoscale(int _autoscale) } VisualizationSceneScalarData::VisualizationSceneScalarData( - Mesh & m, Vector & s, Mesh *mc) - : a_label_x("x"), a_label_y("y"), a_label_z("z") + Window &win_, bool init) : win(win_) { - mesh = &m; - mesh_coarse = mc; - sol = &s; + mesh = win.data_state.mesh.get(); + mesh_coarse = win.data_state.mesh_quad.get(); + sol = &win.data_state.sol; - Init(); + if (init) + { + Init(); + } } void VisualizationSceneScalarData::Init() { vsdata = this; + window = &win; wnd = GetAppWindow(); arrow_type = arrow_scaling_type = 0; diff --git a/lib/vsdata.hpp b/lib/vsdata.hpp index 60b61fe5..0020abc1 100644 --- a/lib/vsdata.hpp +++ b/lib/vsdata.hpp @@ -21,8 +21,6 @@ using namespace mfem; -extern thread_local Window win; // defined in glvis.cpp - class Plane { private: @@ -72,9 +70,11 @@ class VisualizationSceneScalarData : public VisualizationScene Mesh *mesh{}, *mesh_coarse{}; Vector *sol{}; + Window &win; + double minv, maxv; - std::string a_label_x, a_label_y, a_label_z; + std::string a_label_x{"x"}, a_label_y{"y"}, a_label_z{"z"}; int scaling, colorbar, drawaxes; Shading shading; @@ -158,9 +158,7 @@ class VisualizationSceneScalarData : public VisualizationScene /// Shrink factor with respect to the element (material) attributes centers double shrinkmat; - VisualizationSceneScalarData() - : a_label_x("x"), a_label_y("y"), a_label_z("z") {} - VisualizationSceneScalarData (Mesh & m, Vector & s, Mesh *mc = NULL); + VisualizationSceneScalarData(Window &win, bool init = true); virtual ~VisualizationSceneScalarData(); diff --git a/lib/vssolution.cpp b/lib/vssolution.cpp index 0033e512..7ec44f61 100644 --- a/lib/vssolution.cpp +++ b/lib/vssolution.cpp @@ -419,20 +419,22 @@ static void KeyF12Pressed() } } -VisualizationSceneSolution::VisualizationSceneSolution() -{ - v_normals = NULL; -} - VisualizationSceneSolution::VisualizationSceneSolution( - Mesh &m, Vector &s, Mesh *mc, Vector *normals) + Window &win_, bool init) : VisualizationSceneScalarData(win_, false) { - mesh = &m; - mesh_coarse = mc; - sol = &s; - v_normals = normals; + if (win.data_state.normals.Size() > 0) + { + v_normals = &win.data_state.normals; + } - Init(); + if (init) + { + Init(); + if (win.data_state.grid_f) + { + SetGridFunction(*win.data_state.grid_f); + } + } } void VisualizationSceneSolution::Init() diff --git a/lib/vssolution.hpp b/lib/vssolution.hpp index 86b848ca..b41be912 100644 --- a/lib/vssolution.hpp +++ b/lib/vssolution.hpp @@ -26,7 +26,7 @@ using namespace mfem; class VisualizationSceneSolution : public VisualizationSceneScalarData { protected: - Vector *v_normals; + Vector *v_normals{}; GridFunction *rsol; int drawmesh, drawelems, drawnums, draworder; @@ -86,9 +86,7 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData int attr_to_show, bdr_attr_to_show; Array el_attr_to_show, bdr_el_attr_to_show; - VisualizationSceneSolution(); - VisualizationSceneSolution(Mesh &m, Vector &s, Mesh *mc = NULL, - Vector *normals = NULL); + VisualizationSceneSolution(Window &win, bool init = true); virtual ~VisualizationSceneSolution(); diff --git a/lib/vssolution3d.cpp b/lib/vssolution3d.cpp index 4d927da8..d9e2c1c3 100644 --- a/lib/vssolution3d.cpp +++ b/lib/vssolution3d.cpp @@ -687,18 +687,18 @@ static void KeyF10Pressed() SendExposeEvent(); } -VisualizationSceneSolution3d::VisualizationSceneSolution3d() -{} - -VisualizationSceneSolution3d::VisualizationSceneSolution3d(Mesh &m, Vector &s, - Mesh *mc) +VisualizationSceneSolution3d::VisualizationSceneSolution3d(Window &win_, + bool init) + : VisualizationSceneScalarData(win_, false) { - mesh = &m; - mesh_coarse = mc; - sol = &s; - GridF = NULL; - - Init(); + if (init) + { + Init(); + if (win.data_state.grid_f) + { + SetGridFunction(win.data_state.grid_f.get()); + } + } } diff --git a/lib/vssolution3d.hpp b/lib/vssolution3d.hpp index 0448e128..30ad530e 100644 --- a/lib/vssolution3d.hpp +++ b/lib/vssolution3d.hpp @@ -43,7 +43,7 @@ class VisualizationSceneSolution3d : public VisualizationSceneScalarData int nlevels; Array levels; - GridFunction *GridF; + GridFunction *GridF{}; void Init(); @@ -119,8 +119,7 @@ class VisualizationSceneSolution3d : public VisualizationSceneScalarData Array bdr_attr_to_show; - VisualizationSceneSolution3d(); - VisualizationSceneSolution3d(Mesh & m, Vector & s, Mesh *mc); + VisualizationSceneSolution3d(Window &win, bool init = true); void SetGridFunction (GridFunction *gf) { GridF = gf; } diff --git a/lib/vsvector.cpp b/lib/vsvector.cpp index 926e9c8a..16283540 100644 --- a/lib/vsvector.cpp +++ b/lib/vsvector.cpp @@ -256,56 +256,50 @@ const char *Vec2ScalarNames[7] = "curl", "anisotropy" }; -VisualizationSceneVector::VisualizationSceneVector(Mesh & m, - Vector & sx, Vector & sy, Mesh *mc) +VisualizationSceneVector::VisualizationSceneVector(Window &win_) + : VisualizationSceneSolution(win_, false) { - mesh = &m; - mesh_coarse = mc; - solx = &sx; - soly = &sy; - - sol = new Vector(mesh -> GetNV()); + if (win.data_state.grid_f) + { + FiniteElementSpace *fes = win.data_state.grid_f->FESpace(); + if (fes == NULL || win.data_state.grid_f->VectorDim() != 2) + { + cout << "VisualizationSceneVector::VisualizationSceneVector" << endl; + exit(1); + } - VecGridF = NULL; + VecGridF = win.data_state.grid_f.get(); - Init(); -} + solx = new Vector(mesh -> GetNV()); + soly = new Vector(mesh -> GetNV()); -VisualizationSceneVector::VisualizationSceneVector(GridFunction &vgf) -{ - FiniteElementSpace *fes = vgf.FESpace(); - if (fes == NULL || vgf.VectorDim() != 2) + VecGridF->GetNodalValues(*solx, 1); + VecGridF->GetNodalValues(*soly, 2); + } + else { - cout << "VisualizationSceneVector::VisualizationSceneVector" << endl; - exit(1); + solx = &win.data_state.solu; + soly = &win.data_state.solv; } - VecGridF = &vgf; - - mesh = fes->GetMesh(); - - solx = new Vector(mesh -> GetNV()); - soly = new Vector(mesh -> GetNV()); - - vgf.GetNodalValues (*solx, 1); - vgf.GetNodalValues (*soly, 2); + sol = new Vector(mesh -> GetNV()); - sol = new Vector(mesh -> GetNV()); + Init(); - // VisualizationSceneSolution::Init() sets rsol = NULL ! + if (VecGridF) { - Init(); - SetGridFunction(vgf); - } + // VisualizationSceneSolution::Init() sets rsol = NULL ! + SetGridFunction(*VecGridF); - mesh->GetNodes(vc0); - if (vc0.Size() != vgf.Size()) - { - vc0.Destroy(); - } - else - { - vc0 += vgf; + mesh->GetNodes(vc0); + if (vc0.Size() != VecGridF->Size()) + { + vc0.Destroy(); + } + else + { + vc0 += *VecGridF; + } } } diff --git a/lib/vsvector.hpp b/lib/vsvector.hpp index c7453bd2..b8c53601 100644 --- a/lib/vsvector.hpp +++ b/lib/vsvector.hpp @@ -26,7 +26,7 @@ class VisualizationSceneVector : public VisualizationSceneSolution gl3::GlDrawable vector_buf; gl3::GlDrawable displine_buf; - GridFunction *VecGridF; + GridFunction *VecGridF{}; void Init(); @@ -48,8 +48,7 @@ class VisualizationSceneVector : public VisualizationSceneSolution int GetFunctionAutoRefineFactor() override; public: - VisualizationSceneVector(Mesh &m, Vector &sx, Vector &sy, Mesh *mc = NULL); - VisualizationSceneVector(GridFunction &vgf); + VisualizationSceneVector(Window &win_); void NewMeshAndSolution(GridFunction &vgf, Mesh *mc = NULL); diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index 308eb8b4..0df11e77 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -341,49 +341,38 @@ void VisualizationSceneVector3d::ToggleScalarFunction() FindNewValueRange(true); } -VisualizationSceneVector3d::VisualizationSceneVector3d(Mesh &m, Vector &sx, - Vector &sy, Vector &sz, Mesh *mc) +VisualizationSceneVector3d::VisualizationSceneVector3d(Window &win_) + : VisualizationSceneSolution3d(win_, false) { - mesh = &m; - mesh_coarse = mc; - solx = &sx; - soly = &sy; - solz = &sz; + if (win.data_state.grid_f) + { + FiniteElementSpace *fes = win.data_state.grid_f->FESpace(); + if (fes == NULL || fes->GetVDim() != 3) + { + cout << "VisualizationSceneVector3d::VisualizationSceneVector3d" << endl; + exit(1); + } - sol = new Vector(mesh->GetNV()); + VecGridF = win.data_state.grid_f.get(); - sfes = NULL; - VecGridF = NULL; + sfes = new FiniteElementSpace(mesh, fes->FEColl(), 1, fes->GetOrdering()); + GridF = new GridFunction(sfes); - Init(); -} + solx = new Vector(mesh->GetNV()); + soly = new Vector(mesh->GetNV()); + solz = new Vector(mesh->GetNV()); -VisualizationSceneVector3d::VisualizationSceneVector3d(GridFunction &vgf, - Mesh *mc) -{ - FiniteElementSpace *fes = vgf.FESpace(); - if (fes == NULL || fes->GetVDim() != 3) + VecGridF->GetNodalValues(*solx, 1); + VecGridF->GetNodalValues(*soly, 2); + VecGridF->GetNodalValues(*solz, 3); + } + else { - cout << "VisualizationSceneVector3d::VisualizationSceneVector3d" << endl; - exit(1); + solx = &win.data_state.solu; + soly = &win.data_state.solv; + solz = &win.data_state.solw; } - VecGridF = &vgf; - - mesh = fes->GetMesh(); - mesh_coarse = mc; - - sfes = new FiniteElementSpace(mesh, fes->FEColl(), 1, fes->GetOrdering()); - GridF = new GridFunction(sfes); - - solx = new Vector(mesh->GetNV()); - soly = new Vector(mesh->GetNV()); - solz = new Vector(mesh->GetNV()); - - vgf.GetNodalValues(*solx, 1); - vgf.GetNodalValues(*soly, 2); - vgf.GetNodalValues(*solz, 3); - sol = new Vector(mesh->GetNV()); Init(); diff --git a/lib/vsvector3d.hpp b/lib/vsvector3d.hpp index b32fe3ea..e15a89b9 100644 --- a/lib/vsvector3d.hpp +++ b/lib/vsvector3d.hpp @@ -26,8 +26,8 @@ class VisualizationSceneVector3d : public VisualizationSceneSolution3d gl3::GlDrawable vector_buf; gl3::GlDrawable displine_buf; - GridFunction *VecGridF; - FiniteElementSpace *sfes; + GridFunction *VecGridF{}; + FiniteElementSpace *sfes{}; void Init(); @@ -39,9 +39,7 @@ class VisualizationSceneVector3d : public VisualizationSceneSolution3d public: int ianim, ianimd, ianimmax, drawdisp; - VisualizationSceneVector3d(Mesh & m, Vector & sx, Vector & sy, Vector & sz, - Mesh *mc = NULL); - VisualizationSceneVector3d (GridFunction &vgf, Mesh *mc = NULL); + VisualizationSceneVector3d(Window &win); void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, GridFunction *new_v); From a0e70ad3d495cf80dd7ea85dd53c78ae91d02a6c Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Fri, 2 May 2025 18:04:25 -0700 Subject: [PATCH 05/65] Moved script functions to ScriptController making Window static. --- glvis.cpp | 5 +++-- lib/script_controller.cpp | 45 +++++++++++++++++---------------------- lib/script_controller.hpp | 32 +++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/glvis.cpp b/glvis.cpp index 29c019e2..72d98734 100644 --- a/glvis.cpp +++ b/glvis.cpp @@ -81,7 +81,7 @@ enum InputOptions }; int input = INPUT_SERVER_MODE; -thread_local Window win; +static thread_local Window win; extern thread_local GLVisCommand* glvis_command; thread_local communication_thread *comm_thread = NULL; @@ -784,7 +784,8 @@ int main (int argc, char *argv[]) } cout << "Running script from file: " << script_file << endl; cout << "You may need to press to execute the script steps." << endl; - PlayScript(scr); + ScriptController script(win); + script.PlayScript(scr); return 0; } diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index 4337593c..d4390e86 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -9,7 +9,7 @@ // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. -#include "window.hpp" +#include "script_controller.hpp" #include "file_reader.hpp" #include "coll_reader.hpp" #include "stream_reader.hpp" @@ -29,18 +29,10 @@ extern int window_w; extern int window_h; extern const char *c_plot_caption; -extern thread_local Window win; - -istream *script = NULL; -int scr_running = 0; -int scr_level = 0; -Vector *init_nodes = NULL; -double scr_min_val, scr_max_val; - bool GLVisInitVis(StreamCollection input_streams); void GLVisStartVis(); -int ScriptReadSolution(istream &scr, DataState& state) +int ScriptController::ScriptReadSolution(istream &scr, DataState &state) { int err_read; string mword,sword; @@ -68,7 +60,7 @@ int ScriptReadSolution(istream &scr, DataState& state) return err_read; } -int ScriptReadQuadrature(istream &scr, DataState& state) +int ScriptController::ScriptReadQuadrature(istream &scr, DataState &state) { int err_read; string mword,sword; @@ -96,7 +88,7 @@ int ScriptReadQuadrature(istream &scr, DataState& state) return err_read; } -int ScriptReadParSolution(istream &scr, DataState& state) +int ScriptController::ScriptReadParSolution(istream &scr, DataState &state) { int np, scr_keep_attr, err_read; string mesh_prefix, sol_prefix; @@ -127,7 +119,7 @@ int ScriptReadParSolution(istream &scr, DataState& state) return err_read; } -int ScriptReadParQuadrature(istream &scr, DataState& state) +int ScriptController::ScriptReadParQuadrature(istream &scr, DataState &state) { int np, scr_keep_attr, err_read; string mesh_prefix, quad_prefix; @@ -158,7 +150,7 @@ int ScriptReadParQuadrature(istream &scr, DataState& state) return err_read; } -int ScriptReadDisplMesh(istream &scr, DataState& state) +int ScriptController::ScriptReadDisplMesh(istream &scr, DataState &state) { DataState meshstate; string word; @@ -218,8 +210,8 @@ int ScriptReadDisplMesh(istream &scr, DataState& state) return 0; } -int ScriptReadDataColl(istream &scr, DataState &state, bool mesh_only = true, - bool quad = false) +int ScriptController::ScriptReadDataColl(istream &scr, DataState &state, + bool mesh_only, bool quad) { int err_read; int type; @@ -255,7 +247,7 @@ int ScriptReadDataColl(istream &scr, DataState &state, bool mesh_only = true, return err_read; } -void ExecuteScriptCommand() +void ScriptController::ExecuteScriptCommand() { if (!script) { @@ -693,32 +685,32 @@ void ExecuteScriptCommand() } } -void ScriptControl(); +thread_local ScriptController *ScriptController::script_ctrl = NULL; -void ScriptIdleFunc() +void ScriptController::ScriptIdleFunc() { - ExecuteScriptCommand(); - if (scr_level == 0) + script_ctrl->ExecuteScriptCommand(); + if (script_ctrl->scr_level == 0) { ScriptControl(); } } -void ScriptControl() +void ScriptController::ScriptControl() { - if (scr_running) + if (script_ctrl->scr_running) { - scr_running = 0; + script_ctrl->scr_running = 0; RemoveIdleFunc(ScriptIdleFunc); } else { - scr_running = 1; + script_ctrl->scr_running = 1; AddIdleFunc(ScriptIdleFunc); } } -void PlayScript(istream &scr) +void ScriptController::PlayScript(istream &scr) { string word; @@ -841,6 +833,7 @@ void PlayScript(istream &scr) scr_level = scr_running = 0; script = &scr; + script_ctrl = this; win.data_state.keys.clear(); // Make sure the singleton object returned by GetMainThread() is diff --git a/lib/script_controller.hpp b/lib/script_controller.hpp index b9ecf838..201aa024 100644 --- a/lib/script_controller.hpp +++ b/lib/script_controller.hpp @@ -14,6 +14,36 @@ #include -void PlayScript(std::istream &scr); +#include "window.hpp" + +class ScriptController +{ + Window &win; + + istream *script = NULL; + int scr_running = 0; + int scr_level = 0; + mfem::Vector *init_nodes = NULL; + double scr_min_val, scr_max_val; + + static int ScriptReadSolution(istream &scr, DataState &state); + static int ScriptReadQuadrature(istream &scr, DataState &state); + static int ScriptReadParSolution(istream &scr, DataState &state); + static int ScriptReadParQuadrature(istream &scr, DataState &state); + int ScriptReadDisplMesh(istream &scr, DataState &state); + int ScriptReadDataColl(istream &scr, DataState &state, bool mesh_only = true, + bool quad = false); + + //key handlers using thread-local singleton + static thread_local ScriptController *script_ctrl; + static void ScriptIdleFunc(); + static void ScriptControl(); + void ExecuteScriptCommand(); + +public: + ScriptController(Window &win_) : win(win_) { } + + void PlayScript(std::istream &scr); +}; #endif // GLVIS_SCRIPT_CONTROLLER_HPP From 8ed454a42dacf3fbf6259c1e1a5b8e04b5d06f2b Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Mon, 5 May 2025 09:59:13 -0700 Subject: [PATCH 06/65] Moved visualization routines to Window and eliminated global cmd-line options. --- glvis.cpp | 258 +++++++------------------------------- lib/CMakeLists.txt | 3 +- lib/script_controller.cpp | 35 ++---- lib/script_controller.hpp | 6 + lib/window.cpp | 177 ++++++++++++++++++++++++++ lib/window.hpp | 23 ++++ makefile | 2 +- 7 files changed, 261 insertions(+), 243 deletions(-) create mode 100644 lib/window.cpp diff --git a/glvis.cpp b/glvis.cpp index 72d98734..675ae403 100644 --- a/glvis.cpp +++ b/glvis.cpp @@ -46,26 +46,6 @@ using namespace mfem; const char *string_none = "(none)"; const char *string_default = "(default)"; -// Global variables for command line arguments -const char *mesh_file = string_none; -const char *sol_file = string_none; -const char *vec_sol_file = string_none; -const char *gfunc_file = string_none; -const char *qfunc_file = string_none; -string dc_protocol = string_default; -int dc_cycle = 0; -const char *arg_keys = string_none; -int pad_digits = 6; -int gf_component = -1; -int qf_component = -1; -int window_x = 0; // not a command line option -int window_y = 0; // not a command line option -int window_w = 400; -int window_h = 350; -const char *window_title = string_default; -const char *c_plot_caption = string_none; -bool secure = socketstream::secure_default; - // Global variables enum InputOptions { @@ -81,183 +61,28 @@ enum InputOptions }; int input = INPUT_SERVER_MODE; -static thread_local Window win; -extern thread_local GLVisCommand* glvis_command; -thread_local communication_thread *comm_thread = NULL; - thread_local GeometryRefiner GLVisGeometryRefiner; -const char *window_titles[] = { "GLVis [mesh]", - "GLVis [scalar data]", - "GLVis [vector data]", - }; - void PrintSampleUsage(ostream &out); -// switch representation of the quadrature function -void SwitchQuadSolution(); - -// Visualize the data in the global variables mesh, sol/grid_f, etc -bool GLVisInitVis(StreamCollection input_streams) -{ - DataState::FieldType field_type = win.data_state.GetType(); - - if (field_type <= DataState::FieldType::MIN - || field_type >= DataState::FieldType::MAX) - { - return false; - } - - const char *win_title = (window_title == string_default) ? - window_titles[(int)field_type] : window_title; - - if (InitVisualization(win_title, window_x, window_y, window_w, window_h)) - { - cerr << "Initializing the visualization failed." << endl; - return false; - } - - if (input_streams.size() > 0) - { - GetAppWindow()->setOnKeyDown(SDLK_SPACE, ThreadsPauseFunc); - glvis_command = new GLVisCommand(win); - comm_thread = new communication_thread(std::move(input_streams), glvis_command); - } - - if (win.data_state.quad_f) - { - GetAppWindow()->setOnKeyDown('Q', SwitchQuadSolution); - } - - double mesh_range = -1.0; - if (field_type == DataState::FieldType::SCALAR - || field_type == DataState::FieldType::MESH) - { - if (win.data_state.grid_f) - { - win.data_state.grid_f->GetNodalValues(win.data_state.sol); - } - if (win.data_state.mesh->SpaceDimension() == 2) - { - win.vs = new VisualizationSceneSolution(win); - - if (field_type == DataState::FieldType::MESH) - { - win.vs->OrthogonalProjection = 1; - win.vs->SetLight(false); - win.vs->Zoom(1.8); - // Use the 'bone' palette when visualizing a 2D mesh only (otherwise - // the 'jet-like' palette is used in 2D, see vssolution.cpp). - win.vs->palette.SetIndex(4); - } - } - else if (win.data_state.mesh->SpaceDimension() == 3) - { - VisualizationSceneSolution3d *vss; - win.vs = vss = new VisualizationSceneSolution3d(win); - - if (field_type == DataState::FieldType::MESH) - { - if (win.data_state.mesh->Dimension() == 3) - { - // Use the 'white' palette when visualizing a 3D volume mesh only - vss->palette.SetIndex(11); - vss->SetLightMatIdx(4); - } - else - { - // Use the 'bone' palette when visualizing a surface mesh only - vss->palette.SetIndex(4); - } - // Otherwise, the 'vivid' palette is used in 3D see vssolution3d.cpp - vss->ToggleDrawAxes(); - vss->ToggleDrawMesh(); - } - } - if (field_type == DataState::FieldType::MESH) - { - if (win.data_state.grid_f) - { - mesh_range = win.data_state.grid_f->Max() + 1.0; - } - else - { - mesh_range = win.data_state.sol.Max() + 1.0; - } - } - } - else if (field_type == DataState::FieldType::VECTOR) - { - if (win.data_state.mesh->SpaceDimension() == 2) - { - win.vs = new VisualizationSceneVector(win); - } - else if (win.data_state.mesh->SpaceDimension() == 3) - { - if (win.data_state.grid_f) - { - win.data_state.ProjectVectorFEGridFunction(); - } - win.vs = new VisualizationSceneVector3d(win); - } - } - - if (win.vs) - { - // increase the refinement factors if visualizing a GridFunction - if (win.data_state.grid_f) - { - win.vs->AutoRefine(); - win.vs->SetShading(VisualizationSceneScalarData::Shading::Noncomforming, true); - } - if (mesh_range > 0.0) - { - win.vs->SetValueRange(-mesh_range, mesh_range); - win.vs->SetAutoscale(0); - } - if (win.data_state.mesh->SpaceDimension() == 2 - && field_type == DataState::FieldType::MESH) - { - SetVisualizationScene(win.vs, 2, win.data_state.keys.c_str()); - } - else - { - SetVisualizationScene(win.vs, 3, win.data_state.keys.c_str()); - } - } - return true; -} - -void GLVisStartVis() -{ - RunVisualization(); // deletes win.vs - win.vs = NULL; - if (glvis_command) - { - glvis_command->Terminate(); - delete comm_thread; - delete glvis_command; - glvis_command = NULL; - } - cout << "GLVis window closed." << endl; -} - class Session { StreamCollection input_streams; - DataState state; + Window win; std::thread handler; public: Session(bool fix_elem_orient, - bool save_coloring) + bool save_coloring, + string plot_caption) { - state.fix_elem_orient = fix_elem_orient; - state.save_coloring = save_coloring; + win.data_state.fix_elem_orient = fix_elem_orient; + win.data_state.save_coloring = save_coloring; + win.plot_caption = plot_caption; } - Session(DataState other_state) - : state(std::move(other_state)) + Session(Window other_win) + : win(std::move(other_win)) { } ~Session() = default; @@ -265,27 +90,20 @@ class Session Session(Session&& from) = default; Session& operator= (Session&& from) = default; - inline DataState& GetState() { return state; } - inline const DataState& GetState() const { return state; } + inline DataState& GetState() { return win.data_state; } + inline const DataState& GetState() const { return win.data_state; } void StartSession() { - auto funcThread = [](DataState thread_state, StreamCollection is) + auto funcThread = [](Window w, StreamCollection is) { - // Set thread-local stream state - win.data_state = std::move(thread_state); - if (c_plot_caption != string_none) - { - win.plot_caption = c_plot_caption; - } - - if (GLVisInitVis(std::move(is))) + if (w.GLVisInitVis(std::move(is))) { - GLVisStartVis(); + w.GLVisStartVis(); } }; handler = std::thread {funcThread, - std::move(state), std::move(input_streams)}; + std::move(win), std::move(input_streams)}; handler.detach(); } @@ -299,7 +117,7 @@ class Session } string data_type; *ifs >> data_type >> ws; - StreamReader reader(state); + StreamReader reader(win.data_state); reader.ReadStream(*ifs, data_type); input_streams.emplace_back(std::move(ifs)); @@ -310,7 +128,7 @@ class Session int StartStreamSession(std::unique_ptr &&stream, const std::string &data_type) { - StreamReader reader(state); + StreamReader reader(win.data_state); int ierr = reader.ReadStream(*stream, data_type); if (ierr) { return ierr; } input_streams.emplace_back(std::move(stream)); @@ -321,7 +139,7 @@ class Session int StartStreamSession(StreamCollection &&streams) { - StreamReader reader(state); + StreamReader reader(win.data_state); int ierr = reader.ReadStreams(streams); if (ierr) { return ierr; } input_streams = std::move(streams); @@ -333,7 +151,7 @@ class Session }; void GLVisServer(int portnum, bool save_stream, bool fix_elem_orient, - bool save_coloring) + bool save_coloring, string plot_caption) { std::vector current_sessions; string data_type; @@ -483,7 +301,7 @@ void GLVisServer(int portnum, bool save_stream, bool fix_elem_orient, while (1); } - Session new_session(fix_elem_orient, save_coloring); + Session new_session(fix_elem_orient, save_coloring, plot_caption); constexpr int tmp_filename_size = 50; char tmp_file[tmp_filename_size]; @@ -530,7 +348,23 @@ int main (int argc, char *argv[]) // SDL_main(). SDL_SetMainReady(); #endif + // main Window structure + Window win; + // variables for command line arguments + const char *mesh_file = string_none; + const char *sol_file = string_none; + const char *vec_sol_file = string_none; + const char *gfunc_file = string_none; + const char *qfunc_file = string_none; + string dc_protocol = string_default; + int dc_cycle = 0; + const char *arg_keys = string_none; + int pad_digits = 6; + int gf_component = -1; + int qf_component = -1; + const char *c_plot_caption = string_none; + bool secure = socketstream::secure_default; const char *visit_coll = string_none; const char *sidre_coll = string_none; const char *fms_coll = string_none; @@ -619,11 +453,11 @@ int main (int argc, char *argv[]) " visualization."); args.AddOption(&stream_file, "-saved", "--saved-stream", "Load a GLVis stream saved to a file."); - args.AddOption(&window_w, "-ww", "--window-width", + args.AddOption(&win.window_w, "-ww", "--window-width", "Set the window width."); - args.AddOption(&window_h, "-wh", "--window-height", + args.AddOption(&win.window_h, "-wh", "--window-height", "Set the window height."); - args.AddOption(&window_title, "-wt", "--window-title", + args.AddOption(&win.window_title, "-wt", "--window-title", "Set the window title."); args.AddOption(&c_plot_caption, "-c", "--plot-caption", "Set the plot caption (visible when colorbar is visible)."); @@ -762,7 +596,8 @@ int main (int argc, char *argv[]) GetMainThread(); Session stream_session(win.data_state.fix_elem_orient, - win.data_state.save_coloring); + win.data_state.save_coloring, + win.plot_caption); if (!stream_session.StartSavedSession(stream_file)) { @@ -831,7 +666,8 @@ int main (int argc, char *argv[]) // Run server in new thread std::thread serverThread{GLVisServer, portnum, save_stream, win.data_state.fix_elem_orient, - win.data_state.save_coloring}; + win.data_state.save_coloring, + win.plot_caption}; // Start SDL in main thread SDLMainLoop(true); @@ -945,7 +781,7 @@ int main (int argc, char *argv[]) // initialized from the main thread. GetMainThread(); - Session single_session(std::move(win.data_state)); + Session single_session(std::move(win)); single_session.StartSession(); SDLMainLoop(); @@ -974,11 +810,3 @@ void PrintSampleUsage(ostream &os) " glvis -np <#proc> -m [-q ]\n\n" "All Options:\n"; } - -void SwitchQuadSolution() -{ - int iqs = ((int)win.data_state.GetQuadSolution()+1) - % ((int)DataState::QuadSolution::MAX); - win.data_state.SwitchQuadSolution((DataState::QuadSolution)iqs, win.vs); - SendExposeEvent(); -} diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 89d963d5..4f63a6c0 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -33,7 +33,8 @@ list(APPEND SOURCES vssolution.cpp vssolution3d.cpp vsvector.cpp - vsvector3d.cpp) + vsvector3d.cpp + window.cpp) list(APPEND HEADERS gl/attr_traits.hpp diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index d4390e86..a56039c1 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -21,17 +21,6 @@ using namespace mfem; extern const char *string_none; extern const char *string_default; -extern string dc_protocol; -extern int dc_cycle; -extern int window_x; -extern int window_y; -extern int window_w; -extern int window_h; -extern const char *c_plot_caption; - -bool GLVisInitVis(StreamCollection input_streams); -void GLVisStartVis(); - int ScriptController::ScriptReadSolution(istream &scr, DataState &state) { int err_read; @@ -571,10 +560,10 @@ void ScriptController::ExecuteScriptCommand() } else if (word == "window") { - scr >> window_x >> window_y >> window_w >> window_h; - cout << "Script: window: " << window_x << ' ' << window_y - << ' ' << window_w << ' ' << window_h << endl; - MoveResizeWindow(window_x, window_y, window_w, window_h); + scr >> win.window_x >> win.window_y >> win.window_w >> win.window_h; + cout << "Script: window: " << win.window_x << ' ' << win.window_y + << ' ' << win.window_w << ' ' << win.window_h << endl; + MoveResizeWindow(win.window_x, win.window_y, win.window_w, win.window_h); MyExpose(); } else if (word == "keys") @@ -734,7 +723,7 @@ void ScriptController::PlayScript(istream &scr) scr >> word; if (word == "window") { - scr >> window_x >> window_y >> window_w >> window_h; + scr >> win.window_x >> win.window_y >> win.window_w >> win.window_h; } else if (word == "data_coll_cycle") { @@ -842,21 +831,15 @@ void ScriptController::PlayScript(istream &scr) std::thread worker_thread { - [&](DataState local_state) + [&](Window local_win) { - // set the thread-local DataState - win.data_state = std::move(local_state); - if (c_plot_caption != string_none) - { - win.plot_caption = c_plot_caption; - } - if (GLVisInitVis({})) + if (local_win.GLVisInitVis({})) { GetAppWindow()->setOnKeyDown(SDLK_SPACE, ScriptControl); - GLVisStartVis(); + local_win.GLVisStartVis(); } }, - std::move(win.data_state) + std::move(win) }; SDLMainLoop(); diff --git a/lib/script_controller.hpp b/lib/script_controller.hpp index 201aa024..ab6d1573 100644 --- a/lib/script_controller.hpp +++ b/lib/script_controller.hpp @@ -16,10 +16,16 @@ #include "window.hpp" +extern const char *string_none; +extern const char *string_default; + class ScriptController { Window &win; + string dc_protocol = string_default; + int dc_cycle = 0; + istream *script = NULL; int scr_running = 0; int scr_level = 0; diff --git a/lib/window.cpp b/lib/window.cpp new file mode 100644 index 00000000..e5cc9d83 --- /dev/null +++ b/lib/window.cpp @@ -0,0 +1,177 @@ +// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced +// at the Lawrence Livermore National Laboratory. All Rights reserved. See files +// LICENSE and NOTICE for details. LLNL-CODE-443271. +// +// This file is part of the GLVis visualization tool and library. For more +// information and source code availability see https://glvis.org. +// +// GLVis is free software; you can redistribute it and/or modify it under the +// terms of the BSD-3 license. We welcome feedback and contributions, see file +// CONTRIBUTING.md for details. + +#include "window.hpp" +#include "visual.hpp" + +extern thread_local GLVisCommand* glvis_command; + +// Visualize the data in the global variables mesh, sol/grid_f, etc +bool Window::GLVisInitVis(StreamCollection input_streams) +{ + DataState::FieldType field_type = data_state.GetType(); + + if (field_type <= DataState::FieldType::MIN + || field_type >= DataState::FieldType::MAX) + { + return false; + } + + static const char *window_titles[] = { "GLVis [mesh]", + "GLVis [scalar data]", + "GLVis [vector data]", + }; + + const char *win_title = (window_title == string_default) ? + window_titles[(int)field_type] : window_title; + + if (InitVisualization(win_title, window_x, window_y, window_w, window_h)) + { + cerr << "Initializing the visualization failed." << endl; + return false; + } + + if (input_streams.size() > 0) + { + GetAppWindow()->setOnKeyDown(SDLK_SPACE, ThreadsPauseFunc); + glvis_command = new GLVisCommand(*this); + comm_thread = new communication_thread(std::move(input_streams), glvis_command); + } + + locwin = this; + + if (data_state.quad_f) + { + GetAppWindow()->setOnKeyDown('Q', SwitchQuadSolution); + } + + double mesh_range = -1.0; + if (field_type == DataState::FieldType::SCALAR + || field_type == DataState::FieldType::MESH) + { + if (data_state.grid_f) + { + data_state.grid_f->GetNodalValues(data_state.sol); + } + if (data_state.mesh->SpaceDimension() == 2) + { + vs = new VisualizationSceneSolution(*this); + + if (field_type == DataState::FieldType::MESH) + { + vs->OrthogonalProjection = 1; + vs->SetLight(false); + vs->Zoom(1.8); + // Use the 'bone' palette when visualizing a 2D mesh only (otherwise + // the 'jet-like' palette is used in 2D, see vssolution.cpp). + vs->palette.SetIndex(4); + } + } + else if (data_state.mesh->SpaceDimension() == 3) + { + VisualizationSceneSolution3d *vss; + vs = vss = new VisualizationSceneSolution3d(*this); + + if (field_type == DataState::FieldType::MESH) + { + if (data_state.mesh->Dimension() == 3) + { + // Use the 'white' palette when visualizing a 3D volume mesh only + vss->palette.SetIndex(11); + vss->SetLightMatIdx(4); + } + else + { + // Use the 'bone' palette when visualizing a surface mesh only + vss->palette.SetIndex(4); + } + // Otherwise, the 'vivid' palette is used in 3D see vssolution3d.cpp + vss->ToggleDrawAxes(); + vss->ToggleDrawMesh(); + } + } + if (field_type == DataState::FieldType::MESH) + { + if (data_state.grid_f) + { + mesh_range = data_state.grid_f->Max() + 1.0; + } + else + { + mesh_range = data_state.sol.Max() + 1.0; + } + } + } + else if (field_type == DataState::FieldType::VECTOR) + { + if (data_state.mesh->SpaceDimension() == 2) + { + vs = new VisualizationSceneVector(*this); + } + else if (data_state.mesh->SpaceDimension() == 3) + { + if (data_state.grid_f) + { + data_state.ProjectVectorFEGridFunction(); + } + vs = new VisualizationSceneVector3d(*this); + } + } + + if (vs) + { + // increase the refinement factors if visualizing a GridFunction + if (data_state.grid_f) + { + vs->AutoRefine(); + vs->SetShading(VisualizationSceneScalarData::Shading::Noncomforming, true); + } + if (mesh_range > 0.0) + { + vs->SetValueRange(-mesh_range, mesh_range); + vs->SetAutoscale(0); + } + if (data_state.mesh->SpaceDimension() == 2 + && field_type == DataState::FieldType::MESH) + { + SetVisualizationScene(vs, 2, data_state.keys.c_str()); + } + else + { + SetVisualizationScene(vs, 3, data_state.keys.c_str()); + } + } + return true; +} + +void Window::GLVisStartVis() +{ + RunVisualization(); // deletes vs + vs = NULL; + if (glvis_command) + { + glvis_command->Terminate(); + delete comm_thread; + delete glvis_command; + glvis_command = NULL; + } + cout << "GLVis window closed." << endl; +} + +thread_local Window *Window::locwin = NULL; + +void Window::SwitchQuadSolution() +{ + int iqs = ((int)locwin->data_state.GetQuadSolution()+1) + % ((int)DataState::QuadSolution::MAX); + locwin->data_state.SwitchQuadSolution((DataState::QuadSolution)iqs, locwin->vs); + SendExposeEvent(); +} diff --git a/lib/window.hpp b/lib/window.hpp index 8f880177..0ec15a88 100644 --- a/lib/window.hpp +++ b/lib/window.hpp @@ -15,15 +15,38 @@ #include #include "data_state.hpp" +#include "stream_reader.hpp" class VisualizationSceneScalarData; +class communication_thread; + +extern const char *string_none; +extern const char *string_default; struct Window { DataState data_state; VisualizationSceneScalarData *vs = NULL; + communication_thread *comm_thread = NULL; + + int window_x = 0; // not a command line option + int window_y = 0; // not a command line option + int window_w = 400; + int window_h = 350; + const char *window_title = string_default; std::string plot_caption; std::string extra_caption; + + /// Visualize the data in the global variables mesh, sol/grid_f, etc + bool GLVisInitVis(StreamCollection input_streams); + void GLVisStartVis(); + +private: + /// Thread-local singleton for key handlers + static thread_local Window *locwin; + + /// Switch representation of the quadrature function + static void SwitchQuadSolution(); }; #endif // GLVIS_WINDOW_HPP diff --git a/makefile b/makefile index 5f7f538b..3f53000a 100644 --- a/makefile +++ b/makefile @@ -258,7 +258,7 @@ ALL_SOURCE_FILES = \ lib/script_controller.cpp lib/sdl_helper.cpp lib/sdl_main.cpp \ lib/sdl_windows.cpp lib/sdl_x11.cpp lib/stream_reader.cpp \ lib/threads.cpp lib/vsdata.cpp lib/vssolution.cpp lib/vssolution3d.cpp \ - lib/vsvector.cpp lib/vsvector3d.cpp + lib/vsvector.cpp lib/vsvector3d.cpp lib/window.cpp OBJC_SOURCE_FILES = $(if $(NOTMAC),,lib/sdl_mac.mm) DESKTOP_ONLY_SOURCE_FILES = \ lib/gl/renderer_ff.cpp lib/threads.cpp lib/gl2ps.c lib/sdl_x11.cpp From 791cb7d09acd75f8aee4fa8d1b4c436fe8b99c93 Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Mon, 5 May 2025 10:30:05 -0700 Subject: [PATCH 07/65] Moved scene updating methods to Window. --- lib/data_state.cpp | 66 +-------------------------------------- lib/data_state.hpp | 20 ++---------- lib/script_controller.cpp | 2 +- lib/threads.cpp | 2 +- lib/window.cpp | 66 ++++++++++++++++++++++++++++++++++++++- lib/window.hpp | 17 ++++++++++ 6 files changed, 87 insertions(+), 86 deletions(-) diff --git a/lib/data_state.cpp b/lib/data_state.cpp index c678a851..461f233b 100644 --- a/lib/data_state.cpp +++ b/lib/data_state.cpp @@ -10,7 +10,6 @@ // CONTRIBUTING.md for details. #include "data_state.hpp" -#include "visual.hpp" #include @@ -523,8 +522,7 @@ void DataState::SetQuadSolution(QuadSolution quad_type) quad_sol = quad_type; } -void DataState::SwitchQuadSolution(QuadSolution quad_type, - VisualizationScene *vs) +void DataState::SwitchQuadSolution(QuadSolution quad_type) { unique_ptr old_mesh; // we must backup the refined mesh to prevent its deleting @@ -535,7 +533,6 @@ void DataState::SwitchQuadSolution(QuadSolution quad_type, } SetQuadSolution(quad_type); ExtrudeMeshAndSolution(); - ResetMeshAndSolution(*this, vs); } // Replace a given VectorFiniteElement-based grid function (e.g. from a Nedelec @@ -564,67 +561,6 @@ DataState::ProjectVectorFEGridFunction(std::unique_ptr gf) return gf; } -bool DataState::SetNewMeshAndSolution(DataState new_state, - VisualizationScene* vs) -{ - if (new_state.mesh->SpaceDimension() == mesh->SpaceDimension() && - new_state.grid_f->VectorDim() == grid_f->VectorDim()) - { - ResetMeshAndSolution(new_state, vs); - - internal.grid_f = std::move(new_state.internal.grid_f); - internal.mesh = std::move(new_state.internal.mesh); - internal.quad_f = std::move(new_state.internal.quad_f); - internal.mesh_quad = std::move(new_state.internal.mesh_quad); - - return true; - } - else - { - return false; - } -} - -void DataState::ResetMeshAndSolution(DataState &ss, VisualizationScene* vs) -{ - if (ss.mesh->SpaceDimension() == 2) - { - if (ss.grid_f->VectorDim() == 1) - { - VisualizationSceneSolution *vss = - dynamic_cast(vs); - ss.grid_f->GetNodalValues(ss.sol); - vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &ss.sol, - ss.grid_f.get()); - } - else - { - VisualizationSceneVector *vsv = - dynamic_cast(vs); - vsv->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); - } - } - else - { - if (ss.grid_f->VectorDim() == 1) - { - VisualizationSceneSolution3d *vss = - dynamic_cast(vs); - ss.grid_f->GetNodalValues(ss.sol); - vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &ss.sol, - ss.grid_f.get()); - } - else - { - ss.ProjectVectorFEGridFunction(); - - VisualizationSceneVector3d *vss = - dynamic_cast(vs); - vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), ss.grid_f.get()); - } - } -} - void ::VectorExtrudeCoefficient::Eval(Vector &v, ElementTransformation &T, const IntegrationPoint &ip) { diff --git a/lib/data_state.hpp b/lib/data_state.hpp index 47fdc639..3ee65235 100644 --- a/lib/data_state.hpp +++ b/lib/data_state.hpp @@ -144,8 +144,8 @@ struct DataState /// Set the quadrature function representation producing a proxy grid function void SetQuadSolution(QuadSolution type = QuadSolution::LOR_ClosedGL); - /// Switch the quadrature function representation and update the visualization - void SwitchQuadSolution(QuadSolution type, VisualizationScene* vs); + /// Switch the quadrature function representation + void SwitchQuadSolution(QuadSolution type); /// Get the current representation of quadrature solution inline QuadSolution GetQuadSolution() const { return quad_sol; } @@ -158,22 +158,6 @@ struct DataState void ProjectVectorFEGridFunction() { internal.grid_f = ProjectVectorFEGridFunction(std::move(internal.grid_f)); } - - /// Sets a new mesh and solution from another DataState object, and - /// updates the given VisualizationScene pointer with the new data. - /// - /// Mesh space and grid function dimensions must both match the original - /// dimensions of the current DataState. If there is a mismatch in either - /// value, the function will return false, and the mesh/solution will not be - /// updated. - bool SetNewMeshAndSolution(DataState new_state, - VisualizationScene* vs); - - /// Updates the given VisualizationScene pointer with the new data - /// of the given DataState object. - /// @note: Use with caution when the update is compatible - /// @see SetNewMeshAndSolution() - static void ResetMeshAndSolution(DataState &ss, VisualizationScene* vs); }; #endif // GLVIS_DATA_STATE_HPP diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index a56039c1..3575280f 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -359,7 +359,7 @@ void ScriptController::ExecuteScriptCommand() } } - if (win.data_state.SetNewMeshAndSolution(std::move(new_state), win.vs)) + if (win.SetNewMeshAndSolution(std::move(new_state))) { MyExpose(); } diff --git a/lib/threads.cpp b/lib/threads.cpp index 08107e3a..47ef5f8d 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -473,7 +473,7 @@ int GLVisCommand::Execute() new_state.ExtrudeMeshAndSolution(); } } - if (win.data_state.SetNewMeshAndSolution(std::move(new_state), win.vs)) + if (win.SetNewMeshAndSolution(std::move(new_state))) { if (mesh_range > 0.0) { diff --git a/lib/window.cpp b/lib/window.cpp index e5cc9d83..7f319be7 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -166,12 +166,76 @@ void Window::GLVisStartVis() cout << "GLVis window closed." << endl; } +void Window::SwitchQuadSolution(DataState::QuadSolution quad_type) +{ + data_state.SwitchQuadSolution(quad_type); + ResetMeshAndSolution(data_state); +} + +bool Window::SetNewMeshAndSolution(DataState new_state) +{ + if (new_state.mesh->SpaceDimension() == data_state.mesh->SpaceDimension() && + new_state.grid_f->VectorDim() == data_state.grid_f->VectorDim()) + { + ResetMeshAndSolution(new_state); + + data_state = std::move(new_state); + + return true; + } + else + { + return false; + } +} + +void Window::ResetMeshAndSolution(DataState &ss) +{ + if (ss.mesh->SpaceDimension() == 2) + { + if (ss.grid_f->VectorDim() == 1) + { + VisualizationSceneSolution *vss = + dynamic_cast(vs); + ss.grid_f->GetNodalValues(ss.sol); + vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &ss.sol, + ss.grid_f.get()); + } + else + { + VisualizationSceneVector *vsv = + dynamic_cast(vs); + vsv->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); + } + } + else + { + if (ss.grid_f->VectorDim() == 1) + { + VisualizationSceneSolution3d *vss = + dynamic_cast(vs); + ss.grid_f->GetNodalValues(ss.sol); + vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &ss.sol, + ss.grid_f.get()); + } + else + { + ss.ProjectVectorFEGridFunction(); + + VisualizationSceneVector3d *vss = + dynamic_cast(vs); + vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), ss.grid_f.get()); + } + } +} + + thread_local Window *Window::locwin = NULL; void Window::SwitchQuadSolution() { int iqs = ((int)locwin->data_state.GetQuadSolution()+1) % ((int)DataState::QuadSolution::MAX); - locwin->data_state.SwitchQuadSolution((DataState::QuadSolution)iqs, locwin->vs); + locwin->SwitchQuadSolution((DataState::QuadSolution)iqs); SendExposeEvent(); } diff --git a/lib/window.hpp b/lib/window.hpp index 0ec15a88..befde0de 100644 --- a/lib/window.hpp +++ b/lib/window.hpp @@ -41,6 +41,23 @@ struct Window bool GLVisInitVis(StreamCollection input_streams); void GLVisStartVis(); + /// Switch the quadrature function representation and update the visualization + void SwitchQuadSolution(DataState::QuadSolution type); + + /// Sets a new mesh and solution from another DataState object, and + /// updates the VisualizationScene with the new data. + /// + /// Mesh space and grid function dimensions must both match the original + /// dimensions of the current DataState. If there is a mismatch in either + /// value, the function will return false, and the mesh/solution will not be + /// updated. + bool SetNewMeshAndSolution(DataState new_state); + + /// Updates the VisualizationScene with the new data of the given DataState object. + /// @note: Use with caution when the update is compatible + /// @see SetNewMeshAndSolution() + void ResetMeshAndSolution(DataState &ss); + private: /// Thread-local singleton for key handlers static thread_local Window *locwin; From 473d146316f5232d35199880c48e972addcb21da Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Mon, 5 May 2025 11:03:29 -0700 Subject: [PATCH 08/65] Updated aux_js.cpp. --- lib/aux_js.cpp | 131 ++++++++++++++++++------------------------------- 1 file changed, 48 insertions(+), 83 deletions(-) diff --git a/lib/aux_js.cpp b/lib/aux_js.cpp index 7fad3f3b..cad5eacf 100644 --- a/lib/aux_js.cpp +++ b/lib/aux_js.cpp @@ -24,16 +24,12 @@ #include // used in extern context -thread_local std::string plot_caption; -thread_local std::string extra_caption; thread_local mfem::GeometryRefiner GLVisGeometryRefiner; -static VisualizationSceneScalarData * vs = nullptr; - // either bitmap data or png bytes std::vector * screen_state = nullptr; -DataState stream_state; +static Window win; int last_stream_nproc = 1; @@ -60,7 +56,7 @@ void display(std::stringstream & commands, const int w, const int h) if (word == "keys") { std::cout << "parsing 'keys'" << std::endl; - commands >> stream_state.keys; + commands >> win.data_state.keys; } else if (word == "valuerange") { @@ -73,7 +69,7 @@ void display(std::stringstream & commands, const int w, const int h) } } - DataState::FieldType field_type = stream_state.GetType(); + DataState::FieldType field_type = win.data_state.GetType(); if (field_type <= DataState::FieldType::MIN || field_type >= DataState::FieldType::MAX) @@ -86,10 +82,10 @@ void display(std::stringstream & commands, const int w, const int h) return; } - delete vs; - vs = nullptr; + delete win.vs; + win.vs = nullptr; - if (stream_state.quad_f) + if (win.data_state.quad_f) { GetAppWindow()->setOnKeyDown('Q', SwitchQuadSolution); } @@ -98,58 +94,41 @@ void display(std::stringstream & commands, const int w, const int h) if (field_type == DataState::FieldType::SCALAR || field_type == DataState::FieldType::MESH) { - if (stream_state.grid_f) + if (win.data_state.grid_f) { - stream_state.grid_f->GetNodalValues(stream_state.sol); + win.data_state.grid_f->GetNodalValues(win.data_state.sol); } - if (stream_state.mesh->SpaceDimension() == 2) + if (win.data_state.mesh->SpaceDimension() == 2) { - VisualizationSceneSolution * vss; - if (stream_state.normals.Size() > 0) - { - vs = vss = new VisualizationSceneSolution(*stream_state.mesh, stream_state.sol, - stream_state.mesh_quad.get(), &stream_state.normals); - } - else - { - vs = vss = new VisualizationSceneSolution(*stream_state.mesh, stream_state.sol, - stream_state.mesh_quad.get()); - } - if (stream_state.grid_f) - { - vss->SetGridFunction(*stream_state.grid_f); - } + win.vs = new VisualizationSceneSolution(win); + if (field_type == DataState::FieldType::MESH) { - vs->OrthogonalProjection = 1; - vs->SetLight(0); - vs->Zoom(1.8); + win.vs->OrthogonalProjection = 1; + win.vs->SetLight(0); + win.vs->Zoom(1.8); // Use the 'bone' palette when visualizing a 2D mesh only (otherwise // the 'jet-like' palette is used in 2D, see vssolution.cpp). - vs->palette.SetIndex(4); + win.vs->palette.SetIndex(4); } } - else if (stream_state.mesh->SpaceDimension() == 3) + else if (win.data_state.mesh->SpaceDimension() == 3) { VisualizationSceneSolution3d * vss; - vs = vss = new VisualizationSceneSolution3d(*stream_state.mesh, - stream_state.sol, stream_state.mesh_quad.get()); - if (stream_state.grid_f) - { - vss->SetGridFunction(stream_state.grid_f.get()); - } + win.vs = vss = new VisualizationSceneSolution3d(win); + if (field_type == DataState::FieldType::MESH) { - if (stream_state.mesh->Dimension() == 3) + if (win.data_state.mesh->Dimension() == 3) { // Use the 'white' palette when visualizing a 3D volume mesh only - vs->palette.SetIndex(11); + win.vs->palette.SetIndex(11); vss->SetLightMatIdx(4); } else { // Use the 'bone' palette when visualizing a surface mesh only - vs->palette.SetIndex(4); + win.vs->palette.SetIndex(4); } // Otherwise, the 'vivid' palette is used in 3D see vssolution3d.cpp @@ -159,76 +138,62 @@ void display(std::stringstream & commands, const int w, const int h) } if (field_type == DataState::FieldType::MESH) { - if (stream_state.grid_f) + if (win.data_state.grid_f) { - mesh_range = stream_state.grid_f->Max() + 1.0; + mesh_range = win.data_state.grid_f->Max() + 1.0; } else { - mesh_range = stream_state.sol.Max() + 1.0; + mesh_range = win.data_state.sol.Max() + 1.0; } } } else if (field_type == DataState::FieldType::VECTOR) { - if (stream_state.mesh->SpaceDimension() == 2) + if (win.data_state.mesh->SpaceDimension() == 2) { - if (stream_state.grid_f) - { - vs = new VisualizationSceneVector(*stream_state.grid_f); - } - else - { - vs = new VisualizationSceneVector(*stream_state.mesh, stream_state.solu, - stream_state.solv, stream_state.mesh_quad.get()); - } + win.vs = new VisualizationSceneVector(win); } - else if (stream_state.mesh->SpaceDimension() == 3) + else if (win.data_state.mesh->SpaceDimension() == 3) { - if (stream_state.grid_f) + if (win.data_state.grid_f) { - stream_state.ProjectVectorFEGridFunction(); - vs = new VisualizationSceneVector3d(*stream_state.grid_f, - stream_state.mesh_quad.get()); - } - else - { - vs = new VisualizationSceneVector3d(*stream_state.mesh, stream_state.solu, - stream_state.solv, stream_state.solw, - stream_state.mesh_quad.get()); + win.data_state.ProjectVectorFEGridFunction(); } + + win.vs = new VisualizationSceneVector3d(win); } } - if (vs) + if (win.vs) { // increase the refinement factors if visualizing a GridFunction - if (stream_state.grid_f) + if (win.data_state.grid_f) { - vs->AutoRefine(); - vs->SetShading(VisualizationSceneScalarData::Shading::Noncomforming, true); + win.vs->AutoRefine(); + win.vs->SetShading(VisualizationSceneScalarData::Shading::Noncomforming, true); } if (mesh_range > 0.0) { - vs->SetValueRange(-mesh_range, mesh_range); - vs->SetAutoscale(0); + win.vs->SetValueRange(-mesh_range, mesh_range); + win.vs->SetAutoscale(0); } - if (stream_state.mesh->SpaceDimension() == 2 && + if (win.data_state.mesh->SpaceDimension() == 2 && field_type == DataState::FieldType::MESH) { - SetVisualizationScene(vs, 2); + SetVisualizationScene(win.vs, 2); } else { - SetVisualizationScene(vs, 3); + SetVisualizationScene(win.vs, 3); } } - CallKeySequence(stream_state.keys.c_str()); + CallKeySequence(win.data_state.keys.c_str()); if (minv || maxv) { - vs->SetValueRange(minv, maxv); + win.vs->SetValueRange(minv, maxv); } SendExposeEvent(); @@ -282,7 +247,7 @@ void displayParallelStreams(const StringArray & streams, const int w, const int h) { std::stringstream commands(streams[0]); - processParallelStreams(stream_state, streams, &commands); + processParallelStreams(win.data_state, streams, &commands); display(commands, w, h); } @@ -293,7 +258,7 @@ void displayStream(const std::string & stream, const int w, const int h) std::string data_type; ss >> data_type; - StreamReader reader(stream_state); + StreamReader reader(win.data_state); reader.ReadStream(ss, data_type); display(ss, w, h); @@ -306,11 +271,11 @@ int update(DataState & new_state) { double mesh_range = -1.0; - if (stream_state.SetNewMeshAndSolution(std::move(new_state), vs)) + if (win.SetNewMeshAndSolution(std::move(new_state))) { if (mesh_range > 0.0) { - vs->SetValueRange(-mesh_range, mesh_range); + win.vs->SetValueRange(-mesh_range, mesh_range); } SendExposeEvent(); @@ -465,9 +430,9 @@ em::val getScreenBuffer(bool flip_y=false) void SwitchQuadSolution() { - int iqs = ((int)stream_state.GetQuadSolution()+1) + int iqs = ((int)win.data_state.GetQuadSolution()+1) % ((int)DataState::QuadSolution::MAX); - stream_state.SwitchQuadSolution((DataState::QuadSolution)iqs, vs); + win.SwitchQuadSolution((DataState::QuadSolution)iqs); SendExposeEvent(); } From f2286e38cefdd149fda77444a4eba04e7b062896 Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Mon, 5 May 2025 11:18:08 -0700 Subject: [PATCH 09/65] Unified GLVisInitVis() and aux_js. --- lib/aux_js.cpp | 135 +++---------------------------------------------- 1 file changed, 6 insertions(+), 129 deletions(-) diff --git a/lib/aux_js.cpp b/lib/aux_js.cpp index cad5eacf..e3a14f56 100644 --- a/lib/aux_js.cpp +++ b/lib/aux_js.cpp @@ -40,9 +40,6 @@ namespace js using namespace mfem; -/// Switch representation of the quadrature function -void SwitchQuadSolution(); - /// Display a new stream void display(std::stringstream & commands, const int w, const int h) { @@ -69,125 +66,13 @@ void display(std::stringstream & commands, const int w, const int h) } } - DataState::FieldType field_type = win.data_state.GetType(); - - if (field_type <= DataState::FieldType::MIN - || field_type >= DataState::FieldType::MAX) - { - return; - } - - if (InitVisualization("glvis", 0, 0, w, h)) - { - return; - } - - delete win.vs; - win.vs = nullptr; - - if (win.data_state.quad_f) - { - GetAppWindow()->setOnKeyDown('Q', SwitchQuadSolution); - } - - double mesh_range = -1.0; - if (field_type == DataState::FieldType::SCALAR - || field_type == DataState::FieldType::MESH) - { - if (win.data_state.grid_f) - { - win.data_state.grid_f->GetNodalValues(win.data_state.sol); - } - if (win.data_state.mesh->SpaceDimension() == 2) - { - win.vs = new VisualizationSceneSolution(win); + win.window_title = "glvis"; + win.window_x = 0.; + win.window_y = 0.; + win.window_w = w; + win.window_h = h; - if (field_type == DataState::FieldType::MESH) - { - win.vs->OrthogonalProjection = 1; - win.vs->SetLight(0); - win.vs->Zoom(1.8); - // Use the 'bone' palette when visualizing a 2D mesh only (otherwise - // the 'jet-like' palette is used in 2D, see vssolution.cpp). - win.vs->palette.SetIndex(4); - } - } - else if (win.data_state.mesh->SpaceDimension() == 3) - { - VisualizationSceneSolution3d * vss; - win.vs = vss = new VisualizationSceneSolution3d(win); - - if (field_type == DataState::FieldType::MESH) - { - if (win.data_state.mesh->Dimension() == 3) - { - // Use the 'white' palette when visualizing a 3D volume mesh only - win.vs->palette.SetIndex(11); - vss->SetLightMatIdx(4); - } - else - { - // Use the 'bone' palette when visualizing a surface mesh only - win.vs->palette.SetIndex(4); - } - // Otherwise, the 'vivid' palette is used in 3D see vssolution3d.cpp - - vss->ToggleDrawAxes(); - vss->ToggleDrawMesh(); - } - } - if (field_type == DataState::FieldType::MESH) - { - if (win.data_state.grid_f) - { - mesh_range = win.data_state.grid_f->Max() + 1.0; - } - else - { - mesh_range = win.data_state.sol.Max() + 1.0; - } - } - } - else if (field_type == DataState::FieldType::VECTOR) - { - if (win.data_state.mesh->SpaceDimension() == 2) - { - win.vs = new VisualizationSceneVector(win); - } - else if (win.data_state.mesh->SpaceDimension() == 3) - { - if (win.data_state.grid_f) - { - win.data_state.ProjectVectorFEGridFunction(); - } - - win.vs = new VisualizationSceneVector3d(win); - } - } - - if (win.vs) - { - // increase the refinement factors if visualizing a GridFunction - if (win.data_state.grid_f) - { - win.vs->AutoRefine(); - win.vs->SetShading(VisualizationSceneScalarData::Shading::Noncomforming, true); - } - if (mesh_range > 0.0) - { - win.vs->SetValueRange(-mesh_range, mesh_range); - win.vs->SetAutoscale(0); - } - if (win.data_state.mesh->SpaceDimension() == 2 && - field_type == DataState::FieldType::MESH) - { - SetVisualizationScene(win.vs, 2); - } - else - { - SetVisualizationScene(win.vs, 3); - } - } + win.GLVisInitVis({}); CallKeySequence(win.data_state.keys.c_str()); @@ -428,14 +313,6 @@ em::val getScreenBuffer(bool flip_y=false) screen_state->data())); } -void SwitchQuadSolution() -{ - int iqs = ((int)win.data_state.GetQuadSolution()+1) - % ((int)DataState::QuadSolution::MAX); - win.SwitchQuadSolution((DataState::QuadSolution)iqs); - SendExposeEvent(); -} - #ifdef GLVIS_USE_LIBPNG em::val getPNGByteArray() { From 503039b4dcdaabd20387c84a4deb7d99f4ecd58e Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Mon, 5 May 2025 11:52:27 -0700 Subject: [PATCH 10/65] Changed plain pointers to std unique in Window. --- lib/vsdata.cpp | 1 + lib/window.cpp | 45 ++++++++++++++++++++++++++++++++------------- lib/window.hpp | 16 ++++++++++++++-- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index fdd1ffc0..a14c52ab 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -23,6 +23,7 @@ using namespace std; #include "aux_vis.hpp" #include "material.hpp" #include "palettes.hpp" +#include "threads.hpp" #include "gl2ps.h" diff --git a/lib/window.cpp b/lib/window.cpp index 7f319be7..989d428a 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -14,6 +14,23 @@ extern thread_local GLVisCommand* glvis_command; +Window &Window::operator=(Window &&w) +{ + internal = std::move(w.internal); + + data_state = std::move(w.data_state); + + window_x = w.window_x; + window_y = w.window_y; + window_w = w.window_w; + window_h = w.window_h; + window_title = w.window_title; + plot_caption = std::move(w.plot_caption); + extra_caption = std::move(w.extra_caption); + + return *this; +} + // Visualize the data in the global variables mesh, sol/grid_f, etc bool Window::GLVisInitVis(StreamCollection input_streams) { @@ -43,7 +60,8 @@ bool Window::GLVisInitVis(StreamCollection input_streams) { GetAppWindow()->setOnKeyDown(SDLK_SPACE, ThreadsPauseFunc); glvis_command = new GLVisCommand(*this); - comm_thread = new communication_thread(std::move(input_streams), glvis_command); + internal.comm_thread.reset(new communication_thread(std::move(input_streams), + glvis_command)); } locwin = this; @@ -63,7 +81,7 @@ bool Window::GLVisInitVis(StreamCollection input_streams) } if (data_state.mesh->SpaceDimension() == 2) { - vs = new VisualizationSceneSolution(*this); + internal.vs.reset(new VisualizationSceneSolution(*this)); if (field_type == DataState::FieldType::MESH) { @@ -78,7 +96,8 @@ bool Window::GLVisInitVis(StreamCollection input_streams) else if (data_state.mesh->SpaceDimension() == 3) { VisualizationSceneSolution3d *vss; - vs = vss = new VisualizationSceneSolution3d(*this); + vss = new VisualizationSceneSolution3d(*this); + internal.vs.reset(vss); if (field_type == DataState::FieldType::MESH) { @@ -114,7 +133,7 @@ bool Window::GLVisInitVis(StreamCollection input_streams) { if (data_state.mesh->SpaceDimension() == 2) { - vs = new VisualizationSceneVector(*this); + internal.vs.reset(new VisualizationSceneVector(*this)); } else if (data_state.mesh->SpaceDimension() == 3) { @@ -122,7 +141,7 @@ bool Window::GLVisInitVis(StreamCollection input_streams) { data_state.ProjectVectorFEGridFunction(); } - vs = new VisualizationSceneVector3d(*this); + internal.vs.reset(new VisualizationSceneVector3d(*this)); } } @@ -142,11 +161,11 @@ bool Window::GLVisInitVis(StreamCollection input_streams) if (data_state.mesh->SpaceDimension() == 2 && field_type == DataState::FieldType::MESH) { - SetVisualizationScene(vs, 2, data_state.keys.c_str()); + SetVisualizationScene(vs.get(), 2, data_state.keys.c_str()); } else { - SetVisualizationScene(vs, 3, data_state.keys.c_str()); + SetVisualizationScene(vs.get(), 3, data_state.keys.c_str()); } } return true; @@ -155,11 +174,11 @@ bool Window::GLVisInitVis(StreamCollection input_streams) void Window::GLVisStartVis() { RunVisualization(); // deletes vs - vs = NULL; + internal.vs.reset(); if (glvis_command) { glvis_command->Terminate(); - delete comm_thread; + internal.comm_thread.reset(); delete glvis_command; glvis_command = NULL; } @@ -196,7 +215,7 @@ void Window::ResetMeshAndSolution(DataState &ss) if (ss.grid_f->VectorDim() == 1) { VisualizationSceneSolution *vss = - dynamic_cast(vs); + dynamic_cast(internal.vs.get()); ss.grid_f->GetNodalValues(ss.sol); vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &ss.sol, ss.grid_f.get()); @@ -204,7 +223,7 @@ void Window::ResetMeshAndSolution(DataState &ss) else { VisualizationSceneVector *vsv = - dynamic_cast(vs); + dynamic_cast(internal.vs.get()); vsv->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); } } @@ -213,7 +232,7 @@ void Window::ResetMeshAndSolution(DataState &ss) if (ss.grid_f->VectorDim() == 1) { VisualizationSceneSolution3d *vss = - dynamic_cast(vs); + dynamic_cast(internal.vs.get()); ss.grid_f->GetNodalValues(ss.sol); vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &ss.sol, ss.grid_f.get()); @@ -223,7 +242,7 @@ void Window::ResetMeshAndSolution(DataState &ss) ss.ProjectVectorFEGridFunction(); VisualizationSceneVector3d *vss = - dynamic_cast(vs); + dynamic_cast(internal.vs.get()); vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), ss.grid_f.get()); } } diff --git a/lib/window.hpp b/lib/window.hpp index befde0de..b4f18b47 100644 --- a/lib/window.hpp +++ b/lib/window.hpp @@ -25,9 +25,17 @@ extern const char *string_default; struct Window { +private: + struct + { + std::unique_ptr vs; + std::unique_ptr comm_thread; + } internal; + +public: DataState data_state; - VisualizationSceneScalarData *vs = NULL; - communication_thread *comm_thread = NULL; + const std::unique_ptr &vs{internal.vs}; + const std::unique_ptr &comm_thread{internal.comm_thread}; int window_x = 0; // not a command line option int window_y = 0; // not a command line option @@ -37,6 +45,10 @@ struct Window std::string plot_caption; std::string extra_caption; + Window() = default; + Window(Window &&w) { *this = std::move(w); } + Window& operator=(Window &&w); + /// Visualize the data in the global variables mesh, sol/grid_f, etc bool GLVisInitVis(StreamCollection input_streams); void GLVisStartVis(); From c9df9fb7dea546de3c2933e4bcc477ad1892ffe3 Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Mon, 5 May 2025 12:25:36 -0700 Subject: [PATCH 11/65] Included GLVisCommand in Window and made static a few other variables in aux_vis.cpp. --- lib/aux_vis.cpp | 20 +++++++++++++------- lib/aux_vis.hpp | 3 +++ lib/window.cpp | 10 ++++------ lib/window.hpp | 3 +++ 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index d7e4b282..54e16025 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -35,9 +35,9 @@ using namespace mfem; -thread_local int visualize = 0; +static thread_local int visualize = 0; thread_local VisualizationScene * locscene; -thread_local GLVisCommand *glvis_command = NULL; +static thread_local GLVisCommand *glvis_command = NULL; #ifdef GLVIS_MULTISAMPLE static int glvis_multisample = GLVIS_MULTISAMPLE; @@ -45,17 +45,23 @@ static int glvis_multisample = GLVIS_MULTISAMPLE; static int glvis_multisample = -1; #endif -float line_w = 1.f; -float line_w_aa = gl3::LINE_WIDTH_AA; +static float line_w = 1.f; +static float line_w_aa = gl3::LINE_WIDTH_AA; + +static thread_local SdlWindow * wnd = nullptr; +static bool wndLegacyGl = false; +bool wndUseHiDPI = true; // shared with sdl_main.cpp -thread_local SdlWindow * wnd = nullptr; -bool wndLegacyGl = false; -bool wndUseHiDPI = true; void SDLMainLoop(bool server_mode) { SdlWindow::StartSDL(server_mode); } +void SetGLVisCommand(GLVisCommand *cmd) +{ + glvis_command = cmd; +} + SdlWindow * GetAppWindow() { return wnd; diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index 9929639b..4f412247 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -23,6 +23,9 @@ void SDLMainLoop(bool server_mode = false); +class GLVisCommand; +void SetGLVisCommand(GLVisCommand *cmd); + /// Initializes the visualization and some keys. int InitVisualization(const char name[], int x, int y, int w, int h); diff --git a/lib/window.cpp b/lib/window.cpp index 989d428a..96b9e7a8 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -12,8 +12,6 @@ #include "window.hpp" #include "visual.hpp" -extern thread_local GLVisCommand* glvis_command; - Window &Window::operator=(Window &&w) { internal = std::move(w.internal); @@ -59,9 +57,10 @@ bool Window::GLVisInitVis(StreamCollection input_streams) if (input_streams.size() > 0) { GetAppWindow()->setOnKeyDown(SDLK_SPACE, ThreadsPauseFunc); - glvis_command = new GLVisCommand(*this); + internal.glvis_command.reset(new GLVisCommand(*this)); + SetGLVisCommand(glvis_command.get()); internal.comm_thread.reset(new communication_thread(std::move(input_streams), - glvis_command)); + glvis_command.get())); } locwin = this; @@ -179,8 +178,7 @@ void Window::GLVisStartVis() { glvis_command->Terminate(); internal.comm_thread.reset(); - delete glvis_command; - glvis_command = NULL; + internal.glvis_command.reset(); } cout << "GLVis window closed." << endl; } diff --git a/lib/window.hpp b/lib/window.hpp index b4f18b47..b9f794cd 100644 --- a/lib/window.hpp +++ b/lib/window.hpp @@ -19,6 +19,7 @@ class VisualizationSceneScalarData; class communication_thread; +class GLVisCommand; extern const char *string_none; extern const char *string_default; @@ -30,12 +31,14 @@ struct Window { std::unique_ptr vs; std::unique_ptr comm_thread; + std::unique_ptr glvis_command; } internal; public: DataState data_state; const std::unique_ptr &vs{internal.vs}; const std::unique_ptr &comm_thread{internal.comm_thread}; + const std::unique_ptr &glvis_command{internal.glvis_command}; int window_x = 0; // not a command line option int window_y = 0; // not a command line option From e2e01bbb3e3c4f3cc80aee3e9c6b79977aa2c096 Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Mon, 5 May 2025 12:37:27 -0700 Subject: [PATCH 12/65] Made locscene local. --- lib/aux_vis.cpp | 2 +- lib/vsdata.cpp | 51 +++++++++++++++++++++++----------------------- lib/vssolution.cpp | 1 - lib/vsvector.cpp | 1 - lib/vsvector3d.cpp | 16 ++++++++------- 5 files changed, 35 insertions(+), 36 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 54e16025..16efccb7 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -36,7 +36,7 @@ using namespace mfem; static thread_local int visualize = 0; -thread_local VisualizationScene * locscene; +static thread_local VisualizationScene *locscene = NULL; static thread_local GLVisCommand *glvis_command = NULL; #ifdef GLVIS_MULTISAMPLE diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index a14c52ab..d80e6fab 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -612,9 +612,8 @@ void VisualizationSceneScalarData::PrepareCaption() GetFont()->getObjectSize(caption, caption_w, caption_h); } -static thread_local VisualizationSceneScalarData * vsdata; +static thread_local VisualizationSceneScalarData *vsdata; static thread_local Window *window; -extern thread_local VisualizationScene * locscene; void KeycPressed(GLenum state) { @@ -717,22 +716,22 @@ void KeyLPressed() void KeyrPressed() { - locscene -> spinning = 0; + window->vs -> spinning = 0; RemoveIdleFunc(MainLoop); vsdata -> CenterObject(); - locscene -> ViewAngle = 45.0; - locscene -> ViewScale = 1.0; - locscene -> ViewCenterX = 0.0; - locscene -> ViewCenterY = 0.0; - locscene->cam.Reset(); + window->vs -> ViewAngle = 45.0; + window->vs -> ViewScale = 1.0; + window->vs -> ViewCenterX = 0.0; + window->vs -> ViewCenterY = 0.0; + window->vs->cam.Reset(); vsdata -> key_r_state = 0; SendExposeEvent(); } void KeyRPressed() { - locscene->spinning = 0; + window->vs->spinning = 0; RemoveIdleFunc(MainLoop); vsdata->Toggle2DView(); SendExposeEvent(); @@ -746,14 +745,14 @@ void KeypPressed(GLenum state) } else { - locscene->palette.NextIndex(); + window->vs->palette.NextIndex(); SendExposeEvent(); } } void KeyPPressed() { - locscene->palette.PrevIndex(); + window->vs->palette.PrevIndex(); SendExposeEvent(); } @@ -912,23 +911,23 @@ void KeyF2Pressed() void KeykPressed() { - locscene->matAlpha -= 0.05; - if (locscene->matAlpha < 0.0) + window->vs->matAlpha -= 0.05; + if (window->vs->matAlpha < 0.0) { - locscene->matAlpha = 0.0; + window->vs->matAlpha = 0.0; } - locscene->GenerateAlphaTexture(); + window->vs->GenerateAlphaTexture(); SendExposeEvent(); } void KeyKPressed() { - locscene->matAlpha += 0.05; - if (locscene->matAlpha > 1.0) + window->vs->matAlpha += 0.05; + if (window->vs->matAlpha > 1.0) { - locscene->matAlpha = 1.0; + window->vs->matAlpha = 1.0; } - locscene->GenerateAlphaTexture(); + window->vs->GenerateAlphaTexture(); SendExposeEvent(); } @@ -946,23 +945,23 @@ void KeyAPressed() void KeyCommaPressed() { - locscene->matAlphaCenter -= 0.25; + window->vs->matAlphaCenter -= 0.25; // vsdata -> EventUpdateColors(); - locscene->GenerateAlphaTexture(); + window->vs->GenerateAlphaTexture(); SendExposeEvent(); #ifdef GLVIS_DEBUG - cout << "MatAlphaCenter = " << locscene->matAlphaCenter << endl; + cout << "MatAlphaCenter = " << window->vs->matAlphaCenter << endl; #endif } void KeyLessPressed() { - locscene->matAlphaCenter += 0.25; + window->vs->matAlphaCenter += 0.25; // vsdata -> EventUpdateColors(); - locscene->GenerateAlphaTexture(); + window->vs->GenerateAlphaTexture(); SendExposeEvent(); #ifdef GLVIS_DEBUG - cout << "MatAlphaCenter = " << locscene->matAlphaCenter << endl; + cout << "MatAlphaCenter = " << window->vs->matAlphaCenter << endl; #endif } @@ -1162,7 +1161,7 @@ void VisualizationSceneScalarData::Toggle2DView() break; } - // if (locscene -> view != 2) // make 'R' work the same in 2D and 3D + // if (window->vs -> view != 2) // make 'R' work the same in 2D and 3D key_r_state = (key_r_state+1)%6; rotmat = newrot.mtx; diff --git a/lib/vssolution.cpp b/lib/vssolution.cpp index 7ec44f61..44638f00 100644 --- a/lib/vssolution.cpp +++ b/lib/vssolution.cpp @@ -26,7 +26,6 @@ using namespace std; thread_local VisualizationSceneSolution *vssol; -extern thread_local VisualizationScene *locscene; extern thread_local GeometryRefiner GLVisGeometryRefiner; #ifdef GLVIS_ISFINITE diff --git a/lib/vsvector.cpp b/lib/vsvector.cpp index 16283540..62345069 100644 --- a/lib/vsvector.cpp +++ b/lib/vsvector.cpp @@ -103,7 +103,6 @@ std::string VisualizationSceneVector::GetHelpString() const } thread_local VisualizationSceneVector * vsvector; -extern thread_local VisualizationScene * locscene; extern thread_local VisualizationSceneSolution * vssol; extern thread_local GeometryRefiner GLVisGeometryRefiner; diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index 0df11e77..ea725a3c 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -115,7 +115,7 @@ std::string VisualizationSceneVector3d::GetHelpString() const } thread_local VisualizationSceneVector3d *vsvector3d; -extern thread_local VisualizationScene *locscene; +static thread_local Window *window; extern thread_local GeometryRefiner GLVisGeometryRefiner; static void KeyDPressed() @@ -150,13 +150,13 @@ static void KeyBPressed() static void KeyrPressed() { - locscene -> spinning = 0; + window->vs -> spinning = 0; RemoveIdleFunc(MainLoop); vsvector3d -> CenterObject(); - locscene -> ViewAngle = 45.0; - locscene -> ViewScale = 1.0; - locscene -> ViewCenterX = 0.0; - locscene -> ViewCenterY = 0.0; + window->vs -> ViewAngle = 45.0; + window->vs -> ViewScale = 1.0; + window->vs -> ViewCenterX = 0.0; + window->vs -> ViewCenterY = 0.0; vsvector3d -> ianim = vsvector3d -> ianimd = 0; vsvector3d -> Prepare(); vsvector3d -> PrepareLines(); @@ -167,7 +167,7 @@ static void KeyrPressed() static void KeyRPressed() { - locscene->spinning = 0; + window->vs->spinning = 0; RemoveIdleFunc(MainLoop); vsvector3d -> ianim = vsvector3d -> ianimd = 0; vsvector3d -> Prepare(); @@ -380,6 +380,8 @@ VisualizationSceneVector3d::VisualizationSceneVector3d(Window &win_) void VisualizationSceneVector3d::Init() { + window = &win; + key_r_state = 0; drawdisp = 0; From 456eb3d21f4f248011991959ad5021c5e8155698 Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Mon, 5 May 2025 12:44:30 -0700 Subject: [PATCH 13/65] Made a few thread-local vis scenes local. --- lib/vssolution3d.cpp | 2 +- lib/vsvector.cpp | 3 +-- lib/vsvector3d.cpp | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/vssolution3d.cpp b/lib/vssolution3d.cpp index d9e2c1c3..ada41aec 100644 --- a/lib/vssolution3d.cpp +++ b/lib/vssolution3d.cpp @@ -21,7 +21,7 @@ using namespace mfem; using namespace std; -thread_local VisualizationSceneSolution3d *vssol3d; +static thread_local VisualizationSceneSolution3d *vssol3d; extern thread_local GeometryRefiner GLVisGeometryRefiner; // Reference geometries with a cut in the middle, based on subdivision of diff --git a/lib/vsvector.cpp b/lib/vsvector.cpp index 62345069..206f47fd 100644 --- a/lib/vsvector.cpp +++ b/lib/vsvector.cpp @@ -102,8 +102,7 @@ std::string VisualizationSceneVector::GetHelpString() const return os.str(); } -thread_local VisualizationSceneVector * vsvector; -extern thread_local VisualizationSceneSolution * vssol; +static thread_local VisualizationSceneVector * vsvector; extern thread_local GeometryRefiner GLVisGeometryRefiner; thread_local int ianim = 0; diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index ea725a3c..c9f99f90 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -114,7 +114,7 @@ std::string VisualizationSceneVector3d::GetHelpString() const return os.str(); } -thread_local VisualizationSceneVector3d *vsvector3d; +static thread_local VisualizationSceneVector3d *vsvector3d; static thread_local Window *window; extern thread_local GeometryRefiner GLVisGeometryRefiner; From 4b1ff381485bb4b270994f6bbb6115b014203de8 Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Mon, 5 May 2025 15:18:10 -0700 Subject: [PATCH 14/65] Fixed setting of attributes from script commands. --- lib/script_controller.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index 3575280f..a3b40369 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -98,6 +98,8 @@ int ScriptController::ScriptReadParSolution(istream &scr, DataState &state) { cout << "(processor attributes); " << flush; } + state.keep_attr = scr_keep_attr; + // read the solution prefix scr >> ws >> sol_prefix; cout << "solution prefix: " << sol_prefix << endl; @@ -129,6 +131,8 @@ int ScriptController::ScriptReadParQuadrature(istream &scr, DataState &state) { cout << "(processor attributes); " << flush; } + state.keep_attr = scr_keep_attr; + // read the quadrature prefix scr >> ws >> quad_prefix; cout << "quadrature prefix: " << quad_prefix << endl; From 44f214fb67f0aa7b834227cc0130fdb59416b1ed Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Mon, 5 May 2025 17:42:25 -0700 Subject: [PATCH 15/65] Fixed default number padding digits. --- lib/coll_reader.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/coll_reader.hpp b/lib/coll_reader.hpp index a0c6f86c..68a5eb20 100644 --- a/lib/coll_reader.hpp +++ b/lib/coll_reader.hpp @@ -19,7 +19,7 @@ class DataCollectionReader { DataState &data; - int pad_digits; + int pad_digits = 6; std::string protocol; public: From 8f743503755ba5958dd6a264db08bbe747a701ce Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Mon, 5 May 2025 17:57:26 -0700 Subject: [PATCH 16/65] Reworked script commands adding console help. --- lib/script_controller.cpp | 967 +++++++++++++++++++++----------------- lib/script_controller.hpp | 5 +- 2 files changed, 551 insertions(+), 421 deletions(-) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index a3b40369..bf11e529 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -15,11 +15,61 @@ #include "stream_reader.hpp" #include "visual.hpp" +#include +#include + using namespace std; using namespace mfem; -extern const char *string_none; -extern const char *string_default; +enum class Command +{ + Mesh, + Solution, + ParSolution, + Quadrature, + ParQuadrature, + DataCollMesh, + DataCollField, + DataCollQuad, + DataCollCycle, + DataCollProto, + Screenshot, + Viewcenter, + Perspective, + Light, + View, + Zoom, + Shading, + Subdivisions, + Valuerange, + Autoscale, + Levellines, + AxisNumberFormat, + ColorbarNumberFormat, + Window, + Keys, + Palette, + PaletteRepeat, + ToggleAttributes, + Rotmat, + Camera, + Scale, + Translate, + PlotCaption, + //---------- + Max +}; + +struct CmdItem +{ + const char *keyword; + const char *params; + const char *desc; + + bool operator==(const string &key) const { return key == keyword; } +}; + +static vector commands; int ScriptController::ScriptReadSolution(istream &scr, DataState &state) { @@ -240,6 +290,55 @@ int ScriptController::ScriptReadDataColl(istream &scr, DataState &state, return err_read; } +void ScriptController::InitCommands() +{ + commands.resize((size_t)Command::Max); + + commands[(size_t)Command::Mesh] = {"mesh", "", "Visualize the mesh."}; + commands[(size_t)Command::Solution] = {"solution", " ", "Visualize the solution."}; + commands[(size_t)Command::ParSolution] = {"psolution", " ", "Visualize the distributed solution."}; + commands[(size_t)Command::Quadrature] = {"quadrature", " ", "Visualize the quadrature."}; + commands[(size_t)Command::ParQuadrature] = {"pquadrature", " ", "Visualize the distributed quadrature."}; + commands[(size_t)Command::DataCollMesh] = {"data_coll_mesh", " ", "Visualize the mesh from data collection."}; + commands[(size_t)Command::DataCollField] = {"data_coll_field", " ", "Visualize the field from data collection."}; + commands[(size_t)Command::DataCollQuad] = {"data_coll_quad", " ", "Visualize the Q-field from data collection."}; + commands[(size_t)Command::DataCollCycle] = {"data_coll_cycle", "", "Preset the cycle of the data collection."}; + commands[(size_t)Command::DataCollProto] = {"data_coll_protocol", "", "Preset the protocol of the data collection."}; + commands[(size_t)Command::Screenshot] = {"screenshot", "", "Take a screenshot, saving it to the file."}; + commands[(size_t)Command::Viewcenter] = {"viewcenter", " ", "Change the viewcenter."}; + commands[(size_t)Command::Perspective] = {"perspective", "", "Turn on or off perspective projection."}; + commands[(size_t)Command::Light] = {"light", "", "Turn on or off light."}; + commands[(size_t)Command::View] = {"view", " ", "Change the solid angle of view."}; + commands[(size_t)Command::Zoom] = {"zoom", "", "Change the zoom factor."}; + commands[(size_t)Command::Shading] = {"shading", "", "Change the shading algorithm."}; + commands[(size_t)Command::Subdivisions] = {"subdivisions", " ", "Change the refinement level."}; + commands[(size_t)Command::Valuerange] = {"valuerange", " ", "Change the value range."}; + commands[(size_t)Command::Autoscale] = {"autoscale", "", "Change the autoscale algorithm."}; + commands[(size_t)Command::Levellines] = {"levellines", " ", "Set the level lines."}; + commands[(size_t)Command::AxisNumberFormat] = {"axis_numberformat", "''", "Set the axis number format."}; + commands[(size_t)Command::ColorbarNumberFormat] = {"colorbar_numberformat", "''", "Set the colorbar number format."}; + commands[(size_t)Command::Window] = {"window", " ", "Set the position and size of the window."}; + commands[(size_t)Command::Keys] = {"keys", "", "Send the control key sequence."}; + commands[(size_t)Command::Palette] = {"palette", "", "Set the palette index."}; + commands[(size_t)Command::PaletteRepeat] = {"palette_repeat", "", "Set the repetition of the palette."}; + commands[(size_t)Command::ToggleAttributes] = {"toggle_attributes", "<1/0> [[<1/0>] ...];", "Toggle visibility of the attributes."}; + commands[(size_t)Command::Rotmat] = {"rotmat", "<[0,0]> <[1,0]> ... <[3,3]>", "Set the rotation matrix."}; + commands[(size_t)Command::Camera] = {"camera", " ... ... ... ", "Set the camera position, direction and upward vector."}; + commands[(size_t)Command::Scale] = {"scale", "", "Set the scaling factor."}; + commands[(size_t)Command::Translate] = {"translate", " ", "Set the translation coordinates."}; + commands[(size_t)Command::PlotCaption] = {"plot_caption", "''", "Set the plot caption."}; +} + +void ScriptController::PrintCommands() +{ + cout << "Available commands are:" << endl; + + for (const CmdItem &ci : commands) + { + cout << "\t" << ci.keyword << " " << ci.params << " - " << ci.desc << endl; + } +} + void ScriptController::ExecuteScriptCommand() { if (!script) @@ -269,6 +368,7 @@ void ScriptController::ExecuteScriptCommand() if (word == "{") { scr_level++; + continue; } else if (word == "}") { @@ -277,401 +377,435 @@ void ScriptController::ExecuteScriptCommand() { scr_level = 0; } + continue; } - else if (word == "data_coll_cycle") - { - scr >> dc_cycle; - } - else if (word == "data_coll_protocol") + + auto it = find(commands.begin(), commands.end(), word); + if (it == commands.end()) { - scr >> dc_protocol; + cout << "Unknown command in script: " << word << endl; + PrintCommands(); + break; } - else if (word == "solution" || word == "mesh" || word == "psolution" - || word == "quadrature" || word == "pquadrature" || word == "data_coll_mesh" - || word == "data_coll_field" || word == "data_coll_quad") - { - DataState new_state; - if (word == "solution") + const Command cmd = (Command)(it - commands.begin()); + switch (cmd) + { + case Command::Mesh: + case Command::Solution: + case Command::ParSolution: + case Command::Quadrature: + case Command::ParQuadrature: + case Command::DataCollField: + case Command::DataCollQuad: { - if (ScriptReadSolution(scr, new_state)) + DataState new_state; + + switch (cmd) { - done_one_command = 1; - continue; + case Command::Solution: + if (ScriptReadSolution(scr, new_state)) + { + done_one_command = 1; + continue; + } + break; + case Command::Quadrature: + if (ScriptReadQuadrature(scr, new_state)) + { + done_one_command = 1; + continue; + } + break; + case Command::Mesh: + if (ScriptReadDisplMesh(scr, new_state)) + { + done_one_command = 1; + continue; + } + if (new_state.mesh == NULL) + { + cout << "Script: unexpected 'mesh' command!" << endl; + done_one_command = 1; + continue; + } + break; + case Command::ParSolution: + if (ScriptReadParSolution(scr, new_state)) + { + done_one_command = 1; + continue; + } + break; + case Command::ParQuadrature: + if (ScriptReadParQuadrature(scr, new_state)) + { + done_one_command = 1; + continue; + } + break; + case Command::DataCollMesh: + if (ScriptReadDataColl(scr, new_state)) + { + done_one_command = 1; + continue; + } + break; + case Command::DataCollField: + if (ScriptReadDataColl(scr, new_state, false)) + { + done_one_command = 1; + continue; + } + break; + case Command::DataCollQuad: + if (ScriptReadDataColl(scr, new_state, false, true)) + { + done_one_command = 1; + continue; + } + break; + default: + break; } - } - else if (word == "quadrature") - { - if (ScriptReadQuadrature(scr, new_state)) + + if (win.SetNewMeshAndSolution(std::move(new_state))) { - done_one_command = 1; - continue; + MyExpose(); + } + else + { + cout << "Different type of mesh / solution." << endl; } } - else if (word == "mesh") + break; + case Command::DataCollCycle: + scr >> dc_cycle; + break; + case Command::DataCollProto: + scr >> dc_protocol; + break; + case Command::Screenshot: { - if (ScriptReadDisplMesh(scr, new_state)) + scr >> ws >> word; + + cout << "Script: screenshot: " << flush; + + if (Screenshot(word.c_str(), true)) { + cout << "Screenshot(" << word << ") failed." << endl; done_one_command = 1; continue; } - if (new_state.mesh == NULL) + cout << "-> " << word << endl; + + if (scr_min_val > win.vs->GetMinV()) { - cout << "Script: unexpected 'mesh' command!" << endl; - done_one_command = 1; - continue; + scr_min_val = win.vs->GetMinV(); } - } - else if (word == "psolution") - { - if (ScriptReadParSolution(scr, new_state)) + if (scr_max_val < win.vs->GetMaxV()) { - done_one_command = 1; - continue; + scr_max_val = win.vs->GetMaxV(); } } - else if (word == "pquadrature") + break; + case Command::Viewcenter: { - if (ScriptReadParQuadrature(scr, new_state)) - { - done_one_command = 1; - continue; - } + scr >> win.vs->ViewCenterX >> win.vs->ViewCenterY; + cout << "Script: viewcenter: " + << win.vs->ViewCenterX << ' ' << win.vs->ViewCenterY << endl; + MyExpose(); } - else if (word == "data_coll_mesh") + break; + case Command::Perspective: { - if (ScriptReadDataColl(scr, new_state)) + scr >> ws >> word; + cout << "Script: perspective: " << word; + if (word == "off") { - done_one_command = 1; - continue; + win.vs->OrthogonalProjection = 1; } - } - else if (word == "data_coll_field") - { - if (ScriptReadDataColl(scr, new_state, false)) + else if (word == "on") { - done_one_command = 1; - continue; + win.vs->OrthogonalProjection = 0; } - } - else if (word == "data_coll_quad") - { - if (ScriptReadDataColl(scr, new_state, false, true)) + else { - done_one_command = 1; - continue; + cout << '?'; } - } - - if (win.SetNewMeshAndSolution(std::move(new_state))) - { + cout << endl; MyExpose(); } - else - { - cout << "Different type of mesh / solution." << endl; - } - } - else if (word == "screenshot") - { - scr >> ws >> word; - - cout << "Script: screenshot: " << flush; - - if (Screenshot(word.c_str(), true)) - { - cout << "Screenshot(" << word << ") failed." << endl; - done_one_command = 1; - continue; - } - cout << "-> " << word << endl; - - if (scr_min_val > win.vs->GetMinV()) - { - scr_min_val = win.vs->GetMinV(); - } - if (scr_max_val < win.vs->GetMaxV()) - { - scr_max_val = win.vs->GetMaxV(); - } - } - else if (word == "viewcenter") - { - scr >> win.vs->ViewCenterX >> win.vs->ViewCenterY; - cout << "Script: viewcenter: " - << win.vs->ViewCenterX << ' ' << win.vs->ViewCenterY << endl; - MyExpose(); - } - else if (word == "perspective") - { - scr >> ws >> word; - cout << "Script: perspective: " << word; - if (word == "off") - { - win.vs->OrthogonalProjection = 1; - } - else if (word == "on") + break; + case Command::Light: { - win.vs->OrthogonalProjection = 0; + scr >> ws >> word; + cout << "Script: light: " << word; + if (word == "off") + { + win.vs->SetLight(false); + } + else if (word == "on") + { + win.vs->SetLight(true); + } + else + { + cout << '?'; + } + cout << endl; + MyExpose(); } - else + break; + case Command::View: { - cout << '?'; + double theta, phi; + scr >> theta >> phi; + cout << "Script: view: " << theta << ' ' << phi << endl; + win.vs->SetView(theta, phi); + MyExpose(); } - cout << endl; - MyExpose(); - } - else if (word == "light") - { - scr >> ws >> word; - cout << "Script: light: " << word; - if (word == "off") + break; + case Command::Zoom: { - win.vs->SetLight(false); + double factor; + scr >> factor; + cout << "Script: zoom: " << factor << endl; + win.vs->Zoom(factor); + MyExpose(); } - else if (word == "on") + break; + case Command::Shading: { - win.vs->SetLight(true); + scr >> ws >> word; + cout << "Script: shading: " << flush; + VisualizationSceneScalarData::Shading s = + VisualizationSceneScalarData::Shading::Invalid; + if (word == "flat") + { + s = VisualizationSceneScalarData::Shading::Flat; + } + else if (word == "smooth") + { + s = VisualizationSceneScalarData::Shading::Smooth; + } + else if (word == "cool") + { + s = VisualizationSceneScalarData::Shading::Noncomforming; + } + if (s != VisualizationSceneScalarData::Shading::Invalid) + { + win.vs->SetShading(s, false); + cout << word << endl; + MyExpose(); + } + else + { + cout << word << " ?" << endl; + } } - else + break; + case Command::Subdivisions: { - cout << '?'; + int t, b; + scr >> t >> b; + cout << "Script: subdivisions: " << flush; + win.vs->SetRefineFactors(t, b); + cout << t << ' ' << b << endl; + MyExpose(); } - cout << endl; - MyExpose(); - } - else if (word == "view") - { - double theta, phi; - scr >> theta >> phi; - cout << "Script: view: " << theta << ' ' << phi << endl; - win.vs->SetView(theta, phi); - MyExpose(); - } - else if (word == "zoom") - { - double factor; - scr >> factor; - cout << "Script: zoom: " << factor << endl; - win.vs->Zoom(factor); - MyExpose(); - } - else if (word == "shading") - { - scr >> ws >> word; - cout << "Script: shading: " << flush; - VisualizationSceneScalarData::Shading s = - VisualizationSceneScalarData::Shading::Invalid; - if (word == "flat") + break; + case Command::Valuerange: { - s = VisualizationSceneScalarData::Shading::Flat; + double min, max; + scr >> min >> max; + cout << "Script: valuerange: " << flush; + win.vs->SetValueRange(min, max); + cout << min << ' ' << max << endl; + MyExpose(); } - else if (word == "smooth") + break; + case Command::Autoscale: { - s = VisualizationSceneScalarData::Shading::Smooth; + scr >> ws >> word; + cout << "Script: autoscale: " << word; + if (word == "off") + { + win.vs->SetAutoscale(0); + } + else if (word == "on") + { + win.vs->SetAutoscale(1); + } + else if (word == "value") + { + win.vs->SetAutoscale(2); + } + else if (word == "mesh") + { + win.vs->SetAutoscale(3); + } + else + { + cout << '?'; + } + cout << endl; } - else if (word == "cool") - { - s = VisualizationSceneScalarData::Shading::Noncomforming; + break; + case Command::Levellines: + { + double min, max; + int num; + scr >> min >> max >> num; + cout << "Script: levellines: " << flush; + win.vs->SetLevelLines(min, max, num); + win.vs->UpdateLevelLines(); + cout << min << ' ' << max << ' ' << num << endl; + MyExpose(); } - if (s != VisualizationSceneScalarData::Shading::Invalid) - { - win.vs->SetShading(s, false); - cout << word << endl; + break; + case Command::AxisNumberFormat: + { + char delim; + string axis_formatting; + scr >> ws >> delim; + getline(scr, axis_formatting, delim); + cout << "Script: axis_numberformat: " << flush; + win.vs->SetAxisNumberFormat(axis_formatting); + cout << axis_formatting << endl; MyExpose(); } - else - { - cout << word << " ?" << endl; + break; + case Command::ColorbarNumberFormat: + { + char delim; + string colorbar_formatting; + scr >> ws >> delim; + getline(scr, colorbar_formatting, delim); + cout << "Script: colorbar_numberformat: " << flush; + win.vs->SetColorbarNumberFormat(colorbar_formatting); + cout << colorbar_formatting << endl; + MyExpose(); } - } - else if (word == "subdivisions") - { - int t, b; - scr >> t >> b; - cout << "Script: subdivisions: " << flush; - win.vs->SetRefineFactors(t, b); - cout << t << ' ' << b << endl; - MyExpose(); - } - else if (word == "valuerange") - { - double min, max; - scr >> min >> max; - cout << "Script: valuerange: " << flush; - win.vs->SetValueRange(min, max); - cout << min << ' ' << max << endl; - MyExpose(); - } - else if (word == "autoscale") - { - scr >> ws >> word; - cout << "Script: autoscale: " << word; - if (word == "off") + break; + case Command::Window: { - win.vs->SetAutoscale(0); + scr >> win.window_x >> win.window_y >> win.window_w >> win.window_h; + cout << "Script: window: " << win.window_x << ' ' << win.window_y + << ' ' << win.window_w << ' ' << win.window_h << endl; + MoveResizeWindow(win.window_x, win.window_y, win.window_w, win.window_h); + MyExpose(); } - else if (word == "on") + break; + case Command::Keys: { - win.vs->SetAutoscale(1); + scr >> win.data_state.keys; + cout << "Script: keys: '" << win.data_state.keys << "'" << endl; + // SendKeySequence(keys.c_str()); + CallKeySequence(win.data_state.keys.c_str()); + MyExpose(); } - else if (word == "value") + break; + case Command::Palette: { - win.vs->SetAutoscale(2); + int pal; + scr >> pal; + cout << "Script: palette: " << pal << endl; + win.vs->palette.SetIndex(pal-1); + MyExpose(); } - else if (word == "mesh") + case Command::PaletteRepeat: { - win.vs->SetAutoscale(3); + int rpt_times; + scr >> rpt_times; + cout << "Script: palette_repeat: " << rpt_times << endl; + win.vs->palette.SetRepeatTimes(rpt_times); + win.vs->palette.GenerateTextures(); + MyExpose(); } - else + break; + case Command::ToggleAttributes: { - cout << '?'; + Array attr_list; + cout << "Script: toggle_attributes:"; + for (scr >> ws; scr.peek() != ';'; scr >> ws) + { + attr_list.Append(0); + scr >> attr_list.Last(); + if (attr_list.Size() <= 256) + { + cout << ' ' << attr_list.Last(); + } + else if (attr_list.Size() == 257) + { + cout << " ... " << flush; + } + } + scr.get(); // read the end symbol: ';' + cout << endl; + win.vs->ToggleAttributes(attr_list); + MyExpose(); } - cout << endl; - } - else if (word == "levellines") - { - double min, max; - int num; - scr >> min >> max >> num; - cout << "Script: levellines: " << flush; - win.vs->SetLevelLines(min, max, num); - win.vs->UpdateLevelLines(); - cout << min << ' ' << max << ' ' << num << endl; - MyExpose(); - } - else if (word == "axis_numberformat") - { - char delim; - string axis_formatting; - scr >> ws >> delim; - getline(scr, axis_formatting, delim); - cout << "Script: axis_numberformat: " << flush; - win.vs->SetAxisNumberFormat(axis_formatting); - cout << axis_formatting << endl; - MyExpose(); - } - else if (word == "colorbar_numberformat") - { - char delim; - string colorbar_formatting; - scr >> ws >> delim; - getline(scr, colorbar_formatting, delim); - cout << "Script: colorbar_numberformat: " << flush; - win.vs->SetColorbarNumberFormat(colorbar_formatting); - cout << colorbar_formatting << endl; - MyExpose(); - } - else if (word == "window") - { - scr >> win.window_x >> win.window_y >> win.window_w >> win.window_h; - cout << "Script: window: " << win.window_x << ' ' << win.window_y - << ' ' << win.window_w << ' ' << win.window_h << endl; - MoveResizeWindow(win.window_x, win.window_y, win.window_w, win.window_h); - MyExpose(); - } - else if (word == "keys") - { - scr >> win.data_state.keys; - cout << "Script: keys: '" << win.data_state.keys << "'" << endl; - // SendKeySequence(keys.c_str()); - CallKeySequence(win.data_state.keys.c_str()); - MyExpose(); - } - else if (word == "palette") - { - int pal; - scr >> pal; - cout << "Script: palette: " << pal << endl; - win.vs->palette.SetIndex(pal-1); - MyExpose(); - } - else if (word == "palette_repeat") - { - int rpt_times; - scr >> rpt_times; - cout << "Script: palette_repeat: " << rpt_times << endl; - win.vs->palette.SetRepeatTimes(rpt_times); - win.vs->palette.GenerateTextures(); - MyExpose(); - } - else if (word == "toggle_attributes") - { - Array attr_list; - cout << "Script: toggle_attributes:"; - for (scr >> ws; scr.peek() != ';'; scr >> ws) + break; + case Command::Rotmat: { - attr_list.Append(0); - scr >> attr_list.Last(); - if (attr_list.Size() <= 256) + cout << "Script: rotmat:"; + for (int i = 0; i < 16; i++) { - cout << ' ' << attr_list.Last(); + scr >> win.vs->rotmat[i/4][i%4]; + cout << ' ' << win.vs->rotmat[i/4][i%4]; } - else if (attr_list.Size() == 257) + cout << endl; + MyExpose(); + } + break; + case Command::Camera: + { + double cam[9]; + cout << "Script: camera:"; + for (int i = 0; i < 9; i++) { - cout << " ... " << flush; + scr >> cam[i]; + cout << ' ' << cam[i]; } + cout << endl; + win.vs->cam.Set(cam); + MyExpose(); } - scr.get(); // read the end symbol: ';' - cout << endl; - win.vs->ToggleAttributes(attr_list); - MyExpose(); - } - else if (word == "rotmat") - { - cout << "Script: rotmat:"; - for (int i = 0; i < 16; i++) - { - scr >> win.vs->rotmat[i/4][i%4]; - cout << ' ' << win.vs->rotmat[i/4][i%4]; + break; + case Command::Scale: + { + double scale; + cout << "Script: scale:"; + scr >> scale; + cout << ' ' << scale; + cout << endl; + win.vs->Scale(scale); + MyExpose(); } - cout << endl; - MyExpose(); - } - else if (word == "camera") - { - double cam[9]; - cout << "Script: camera:"; - for (int i = 0; i < 9; i++) + break; + case Command::Translate: + { + double x, y, z; + cout << "Script: translate:"; + scr >> x >> y >> z; + cout << ' ' << x << ' ' << y << ' ' << z; + cout << endl; + win.vs->Translate(x, y, z); + MyExpose(); + } + break; + case Command::PlotCaption: { - scr >> cam[i]; - cout << ' ' << cam[i]; + char delim; + scr >> ws >> delim; + getline(scr, win.plot_caption, delim); + win.vs->PrepareCaption(); // turn on or off the caption + MyExpose(); } - cout << endl; - win.vs->cam.Set(cam); - MyExpose(); - } - else if (word == "scale") - { - double scale; - cout << "Script: scale:"; - scr >> scale; - cout << ' ' << scale; - cout << endl; - win.vs->Scale(scale); - MyExpose(); - } - else if (word == "translate") - { - double x, y, z; - cout << "Script: translate:"; - scr >> x >> y >> z; - cout << ' ' << x << ' ' << y << ' ' << z; - cout << endl; - win.vs->Translate(x, y, z); - MyExpose(); - } - else if (word == "plot_caption") - { - char delim; - scr >> ws >> delim; - getline(scr, win.plot_caption, delim); - win.vs->PrepareCaption(); // turn on or off the caption - MyExpose(); - } - else - { - cout << "Unknown command in script: " << word << endl; + break; + default: + break; } done_one_command = 1; @@ -703,15 +837,25 @@ void ScriptController::ScriptControl() } } +ScriptController::ScriptController(Window &win_) + : win(win_) +{ + if (commands.empty()) + { + InitCommands(); + } +} + void ScriptController::PlayScript(istream &scr) { string word; + bool done = false; scr_min_val = numeric_limits::infinity(); scr_max_val = -scr_min_val; // read initializing commands - while (1) + while (!done) { scr >> ws; if (!scr.good()) @@ -725,102 +869,85 @@ void ScriptController::PlayScript(istream &scr) continue; } scr >> word; - if (word == "window") - { - scr >> win.window_x >> win.window_y >> win.window_w >> win.window_h; - } - else if (word == "data_coll_cycle") - { - scr >> dc_cycle; - } - else if (word == "data_coll_protocol") - { - scr >> dc_protocol; - } - else if (word == "solution") - { - if (ScriptReadSolution(scr, win.data_state)) - { - return; - } - // start the visualization - break; - } - else if (word == "quadrature") + auto it = find(commands.begin(), commands.end(), word); + if (it == commands.end()) { - if (ScriptReadQuadrature(scr, win.data_state)) - { - return; - } - - // start the visualization - break; - } - else if (word == "psolution") - { - if (ScriptReadParSolution(scr, win.data_state)) - { - return; - } - - // start the visualization - break; + cout << "Unknown command in script: " << word << endl; + PrintCommands(); + return; } - else if (word == "pquadrature") - { - if (ScriptReadParQuadrature(scr, win.data_state)) - { - return; - } - // start the visualization - break; - } - else if (word == "mesh") + const Command cmd = (Command)(it - commands.begin()); + switch (cmd) { - if (ScriptReadDisplMesh(scr, win.data_state)) - { - return; - } - if (win.data_state.mesh) - { + case Command::Window: + scr >> win.window_x >> win.window_y >> win.window_w >> win.window_h; + break; + case Command::DataCollCycle: + scr >> dc_cycle; + break; + case Command::DataCollProto: + scr >> dc_protocol; + break; + case Command::Solution: + if (ScriptReadSolution(scr, win.data_state)) + { + return; + } + done = true; // start the visualization + break; + case Command::Quadrature: + if (ScriptReadQuadrature(scr, win.data_state)) + { + return; + } + done = true; // start the visualization + break; + case Command::ParSolution: + if (ScriptReadParSolution(scr, win.data_state)) + { + return; + } + done = true; // start the visualization + break; + case Command::ParQuadrature: + if (ScriptReadParQuadrature(scr, win.data_state)) + { + return; + } + done = true; // start the visualization + break; + case Command::Mesh: + if (ScriptReadDisplMesh(scr, win.data_state)) + { + return; + } + done = win.data_state.mesh != nullptr; + break; + case Command::DataCollMesh: + if (ScriptReadDataColl(scr, win.data_state)) + { + return; + } + done = true; // start the visualization + break; + case Command::DataCollField: + if (ScriptReadDataColl(scr, win.data_state, false)) + { + return; + } + done = true; // start the visualization + break; + case Command::DataCollQuad: + if (ScriptReadDataColl(scr, win.data_state, false, true)) + { + return; + } + done = true; // start the visualization + break; + default: break; - } - } - else if (word == "data_coll_mesh") - { - if (ScriptReadDataColl(scr, win.data_state)) - { - return; - } - - // start the visualization - break; - } - else if (word == "data_coll_field") - { - if (ScriptReadDataColl(scr, win.data_state, false)) - { - return; - } - - // start the visualization - break; - } - else if (word == "data_coll_quad") - { - if (ScriptReadDataColl(scr, win.data_state, false, true)) - { - return; - } - - // start the visualization - break; - } - else - { - cout << "Unknown command in script: " << word << endl; } } diff --git a/lib/script_controller.hpp b/lib/script_controller.hpp index ab6d1573..44304ab1 100644 --- a/lib/script_controller.hpp +++ b/lib/script_controller.hpp @@ -44,10 +44,13 @@ class ScriptController static thread_local ScriptController *script_ctrl; static void ScriptIdleFunc(); static void ScriptControl(); + + static void InitCommands(); + static void PrintCommands(); void ExecuteScriptCommand(); public: - ScriptController(Window &win_) : win(win_) { } + ScriptController(Window &win_); void PlayScript(std::istream &scr); }; From b021552af7a335d078ba05d6822c5940a672252e Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Mon, 5 May 2025 22:43:15 -0700 Subject: [PATCH 17/65] Fixed double free. --- lib/aux_vis.cpp | 1 - lib/window.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 16efccb7..015f55ca 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -369,7 +369,6 @@ void RunVisualization() wnd->mainLoop(); #endif InitIdleFuncs(); - delete locscene; delete wnd; wnd = nullptr; } diff --git a/lib/window.cpp b/lib/window.cpp index 96b9e7a8..1966069d 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -172,7 +172,7 @@ bool Window::GLVisInitVis(StreamCollection input_streams) void Window::GLVisStartVis() { - RunVisualization(); // deletes vs + RunVisualization(); internal.vs.reset(); if (glvis_command) { From 7323f0281e4c4219c0c6ca52c8448cf120fc4031 Mon Sep 17 00:00:00 2001 From: Jan Nikl Date: Tue, 6 May 2025 01:23:22 -0700 Subject: [PATCH 18/65] Changed streams to commands list. --- lib/script_controller.cpp | 2 +- lib/threads.cpp | 1048 +++++++++++++++++++++---------------- lib/threads.hpp | 2 + 3 files changed, 598 insertions(+), 454 deletions(-) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index bf11e529..56e60a76 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -318,7 +318,7 @@ void ScriptController::InitCommands() commands[(size_t)Command::AxisNumberFormat] = {"axis_numberformat", "''", "Set the axis number format."}; commands[(size_t)Command::ColorbarNumberFormat] = {"colorbar_numberformat", "''", "Set the colorbar number format."}; commands[(size_t)Command::Window] = {"window", " ", "Set the position and size of the window."}; - commands[(size_t)Command::Keys] = {"keys", "", "Send the control key sequence."}; + commands[(size_t)Command::Keys] = {"keys", "", "Send the control key sequence."}; commands[(size_t)Command::Palette] = {"palette", "", "Set the palette index."}; commands[(size_t)Command::PaletteRepeat] = {"palette_repeat", "", "Set the repetition of the palette."}; commands[(size_t)Command::ToggleAttributes] = {"toggle_attributes", "<1/0> [[<1/0>] ...];", "Toggle visibility of the attributes."}; diff --git a/lib/threads.cpp b/lib/threads.cpp index 47ef5f8d..fdad95fe 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -12,6 +12,7 @@ #include "visual.hpp" #include "palettes.hpp" #include +#include using namespace std; @@ -796,6 +797,49 @@ GLVisCommand::~GLVisCommand() } } +enum class Command +{ + Mesh, + Solution, + Quadrature, + Parallel, + Screenshot, + Viewcenter, + View, + Zoom, + Shading, + Subdivisions, + Valuerange, + Autoscale, + Levellines, + AxisNumberFormat, + ColorbarNumberFormat, + WindowSize, + WindowGeometry, + WindowTitle, + Keys, + Palette, + PaletteRepeat, + Camera, + PlotCaption, + AxisLabels, + Pause, + Autopause, + //---------- + Max +}; + +struct CmdItem +{ + const char *keyword; + const char *params; + const char *desc; + + bool operator==(const string &key) const { return key == keyword; } +}; + +static vector commands; + communication_thread::communication_thread(StreamCollection _is, GLVisCommand* cmd) : is(std::move(_is)), glvis_command(cmd) @@ -803,6 +847,11 @@ communication_thread::communication_thread(StreamCollection _is, new_m = NULL; new_g = NULL; + if (commands.empty()) + { + init_commands(); + } + if (is.size() > 0) { tid = std::thread(&communication_thread::execute, this); @@ -818,6 +867,48 @@ communication_thread::~communication_thread() } } +void communication_thread::init_commands() +{ + commands.resize((size_t)Command::Max); + + commands[(size_t)Command::Mesh] = {"mesh", "", "Visualize the mesh."}; + commands[(size_t)Command::Solution] = {"solution", " ", "Visualize the solution."}; + commands[(size_t)Command::Quadrature] = {"quadrature", " ", "Visualize the quadrature."}; + commands[(size_t)Command::Parallel] = {"parallel", " ", "Prefix for distributed mesh/solution/quadrature."}; + commands[(size_t)Command::Screenshot] = {"screenshot", "", "Take a screenshot, saving it to the file."}; + commands[(size_t)Command::Viewcenter] = {"viewcenter", " ", "Change the viewcenter."}; + commands[(size_t)Command::View] = {"view", " ", "Change the solid angle of view."}; + commands[(size_t)Command::Zoom] = {"zoom", "", "Change the zoom factor."}; + commands[(size_t)Command::Shading] = {"shading", "", "Change the shading algorithm."}; + commands[(size_t)Command::Subdivisions] = {"subdivisions", " ", "Change the refinement level."}; + commands[(size_t)Command::Valuerange] = {"valuerange", " ", "Change the value range."}; + commands[(size_t)Command::Autoscale] = {"autoscale", "", "Change the autoscale algorithm."}; + commands[(size_t)Command::Levellines] = {"levellines", " ", "Set the level lines."}; + commands[(size_t)Command::AxisNumberFormat] = {"axis_numberformat", "''", "Set the axis number format."}; + commands[(size_t)Command::ColorbarNumberFormat] = {"colorbar_numberformat", "''", "Set the colorbar number format."}; + commands[(size_t)Command::WindowSize] = {"window_size", " ", "Set the size of the window."}; + commands[(size_t)Command::WindowGeometry] = {"window_geometry", " ", "Set the position and size of the window."}; + commands[(size_t)Command::WindowTitle] = {"window_title", "''", "Set title of the window."}; + commands[(size_t)Command::Keys] = {"keys", "<keys>", "Send the control key sequence."}; + commands[(size_t)Command::Palette] = {"palette", "<index>", "Set the palette index."}; + commands[(size_t)Command::PaletteRepeat] = {"palette_repeat", "<times>", "Set the repetition of the palette."}; + commands[(size_t)Command::Camera] = {"camera", "<cam[0]> ... <cam[2]> <dir[0]> ... <dir[2]> <up[0]> ... <up[2]>", "Set the camera position, direction and upward vector."}; + commands[(size_t)Command::PlotCaption] = {"plot_caption", "'<caption>'", "Set the plot caption."}; + commands[(size_t)Command::AxisLabels] = {"axis_labels", "'<x label>' '<y label>' '<z label>'", "Set labels of the axes."}; + commands[(size_t)Command::Pause] = {"pause", "", "Stop the stream until space is pressed."}; + commands[(size_t)Command::Autopause] = {"autopause", "<0/off/1/on>", "Turns off or on autopause."}; +} + +void communication_thread::print_commands() +{ + cout << "Available commands are:" << endl; + + for (const CmdItem &ci : commands) + { + cout << "\t" << ci.keyword << " " << ci.params << " - " << ci.desc << endl; + } +} + void communication_thread::execute() { while (1) @@ -832,571 +923,622 @@ void communication_thread::execute() break; } - if (ident == "mesh" || ident == "solution" || - ident == "quadrature" || ident == "parallel") + auto it = find(commands.begin(), commands.end(), ident); + if (it == commands.end()) { - bool fix_elem_orient = glvis_command->FixElementOrientations(); - DataState tmp; - if (ident == "mesh") - { - tmp.SetMesh(new Mesh(*is[0], 1, 0, fix_elem_orient)); - if (!(*is[0])) - { - break; - } - tmp.SetGridFunction(NULL); - } - else if (ident == "solution") - { - tmp.SetMesh(new Mesh(*is[0], 1, 0, fix_elem_orient)); - if (!(*is[0])) - { - break; - } - tmp.SetGridFunction(new GridFunction(tmp.mesh.get(), *is[0])); - if (!(*is[0])) - { - break; - } - } - else if (ident == "quadrature") - { - tmp.SetMesh(new Mesh(*is[0], 1, 0, fix_elem_orient)); - if (!(*is[0])) - { - break; - } - tmp.SetQuadFunction(new QuadratureFunction(tmp.mesh.get(), *is[0])); - if (!(*is[0])) + cout << "Stream: unknown command: " << ident << endl; + print_commands(); + goto comm_terminate; + } + + const Command cmd = (Command)(it - commands.begin()); + switch (cmd) + { + case Command::Mesh: + case Command::Solution: + case Command::Quadrature: + case Command::Parallel: + { + bool fix_elem_orient = glvis_command->FixElementOrientations(); + bool done = false; + DataState tmp; + switch (cmd) { + case Command::Mesh: + { + tmp.SetMesh(new Mesh(*is[0], 1, 0, fix_elem_orient)); + if (!(*is[0])) + { + done = true; + break; + } + tmp.SetGridFunction(NULL); + } break; - } - } - else if (ident == "parallel") - { - std::vector<Mesh*> mesh_array; - std::vector<GridFunction*> gf_array; - std::vector<QuadratureFunction*> qf_array; - int proc, nproc, np = 0; - bool keep_attr = glvis_command->KeepAttrib(); - do - { - istream &isock = *is[np]; - isock >> nproc >> proc >> ws; -#ifdef GLVIS_DEBUG - cout << "connection[" << np << "]: parallel " << nproc << ' ' - << proc << endl; -#endif - isock >> ident >> ws; - mesh_array.resize(nproc); - mesh_array[proc] = new Mesh(isock, 1, 0, fix_elem_orient); - if (!keep_attr) + case Command::Solution: { - // set element and boundary attributes to proc+1 - for (int i = 0; i < mesh_array[proc]->GetNE(); i++) + tmp.SetMesh(new Mesh(*is[0], 1, 0, fix_elem_orient)); + if (!(*is[0])) { - mesh_array[proc]->GetElement(i)->SetAttribute(proc+1); + done = true; + break; } - for (int i = 0; i < mesh_array[proc]->GetNBE(); i++) + tmp.SetGridFunction(new GridFunction(tmp.mesh.get(), *is[0])); + if (!(*is[0])) { - mesh_array[proc]->GetBdrElement(i)->SetAttribute(proc+1); + done = true; + break; } } - if (ident == "solution") - { - gf_array.resize(nproc); - gf_array[proc] = new GridFunction(mesh_array[proc], isock); - } - else if (ident == "quadrature") + break; + case Command::Quadrature: { - qf_array.resize(nproc); - qf_array[proc] = new QuadratureFunction(mesh_array[proc], isock); + tmp.SetMesh(new Mesh(*is[0], 1, 0, fix_elem_orient)); + if (!(*is[0])) + { + done = true; + break; + } + tmp.SetQuadFunction(new QuadratureFunction(tmp.mesh.get(), *is[0])); + if (!(*is[0])) + { + done = true; + break; + } } - else + break; + case Command::Parallel: { - cout << "Stream: unknown command: " << ident << endl; + std::vector<Mesh*> mesh_array; + std::vector<GridFunction*> gf_array; + std::vector<QuadratureFunction*> qf_array; + int proc, nproc, np = 0; + bool keep_attr = glvis_command->KeepAttrib(); + do + { + istream &isock = *is[np]; + isock >> nproc >> proc >> ws; +#ifdef GLVIS_DEBUG + cout << "connection[" << np << "]: parallel " << nproc << ' ' + << proc << endl; +#endif + isock >> ident >> ws; + mesh_array.resize(nproc); + mesh_array[proc] = new Mesh(isock, 1, 0, fix_elem_orient); + if (!keep_attr) + { + // set element and boundary attributes to proc+1 + for (int i = 0; i < mesh_array[proc]->GetNE(); i++) + { + mesh_array[proc]->GetElement(i)->SetAttribute(proc+1); + } + for (int i = 0; i < mesh_array[proc]->GetNBE(); i++) + { + mesh_array[proc]->GetBdrElement(i)->SetAttribute(proc+1); + } + } + if (ident == "solution") + { + gf_array.resize(nproc); + gf_array[proc] = new GridFunction(mesh_array[proc], isock); + } + else if (ident == "quadrature") + { + qf_array.resize(nproc); + qf_array[proc] = new QuadratureFunction(mesh_array[proc], isock); + } + else + { + cout << "Stream: unknown command: " << ident << endl; + } + np++; + if (np == nproc) + { + break; + } + *is[np] >> ident >> ws; // "parallel" + } + while (1); + + tmp.SetMesh(new Mesh(mesh_array.data(), nproc)); + if (gf_array.size() > 0) + { + tmp.SetGridFunction(new GridFunction(tmp.mesh.get(), gf_array.data(), nproc)); + } + else if (qf_array.size() > 0) + { + tmp.SetQuadFunction(qf_array); + } + + for (int p = 0; p < nproc; p++) + { + if (gf_array.size() > 0) + { + delete gf_array[nproc-1-p]; + } + if (qf_array.size() > 0) + { + delete qf_array[nproc-1-p]; + } + delete mesh_array[nproc-1-p]; + } + gf_array.clear(); + qf_array.clear(); + mesh_array.clear(); } - np++; - if (np == nproc) - { + break; + default: break; - } - *is[np] >> ident >> ws; // "parallel" } - while (1); + if (done) { break; } - tmp.SetMesh(new Mesh(mesh_array.data(), nproc)); - if (gf_array.size() > 0) + // cout << "Stream: new solution" << endl; + + tmp.ExtrudeMeshAndSolution(); + + if (glvis_command->NewMeshAndSolution(std::move(tmp))) { - tmp.SetGridFunction(new GridFunction(tmp.mesh.get(), gf_array.data(), nproc)); + goto comm_terminate; } - else if (qf_array.size() > 0) + } + break; + case Command::Screenshot: + { + string filename; + + *is[0] >> ws >> filename; + + // all processors sent the screenshot command + for (size_t i = 1; i < is.size(); i++) { - tmp.SetQuadFunction(qf_array); + *is[i] >> ws >> ident; // 'screenshot' + *is[i] >> ws >> ident; // filename } - for (int p = 0; p < nproc; p++) + if (glvis_command->Screenshot(filename.c_str())) { - if (gf_array.size() > 0) - { - delete gf_array[nproc-1-p]; - } - if (qf_array.size() > 0) - { - delete qf_array[nproc-1-p]; - } - delete mesh_array[nproc-1-p]; + goto comm_terminate; } - gf_array.clear(); - qf_array.clear(); - mesh_array.clear(); } + break; + case Command::Keys: + { + string keys; - // cout << "Stream: new solution" << endl; + *is[0] >> ws >> keys; - tmp.ExtrudeMeshAndSolution(); + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'keys' + *is[i] >> ws >> ident; // keys + } - if (glvis_command->NewMeshAndSolution(std::move(tmp))) - { - goto comm_terminate; + if (glvis_command->KeyCommands(keys.c_str())) + { + goto comm_terminate; + } } - } - else if (ident == "screenshot") - { - string filename; - - *is[0] >> ws >> filename; - - // all processors sent the screenshot command - for (size_t i = 1; i < is.size(); i++) + break; + case Command::WindowSize: { - *is[i] >> ws >> ident; // 'screenshot' - *is[i] >> ws >> ident; // filename - } + int w, h, t; - if (glvis_command->Screenshot(filename.c_str())) - { - goto comm_terminate; - } - } - else if (ident == "keys") - { - string keys; + *is[0] >> w >> h; - *is[0] >> ws >> keys; + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'window_size' + *is[i] >> t >> t; + } - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'keys' - *is[i] >> ws >> ident; // keys + if (glvis_command->WindowSize(w, h)) + { + goto comm_terminate; + } } - - if (glvis_command->KeyCommands(keys.c_str())) + break; + case Command::WindowGeometry: { - goto comm_terminate; - } - } - else if (ident == "window_size") - { - int w, h, t; + int x, y, w, h, t; - *is[0] >> w >> h; + *is[0] >> x >> y >> w >> h; - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'window_size' - *is[i] >> t >> t; - } + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'window_geometry' + *is[i] >> t >> t >> t >> t; + } - if (glvis_command->WindowSize(w, h)) - { - goto comm_terminate; + if (glvis_command->WindowGeometry(x, y, w, h)) + { + goto comm_terminate; + } } - } - else if (ident == "window_geometry") - { - int x, y, w, h, t; - - *is[0] >> x >> y >> w >> h; - - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) + break; + case Command::WindowTitle: { - *is[i] >> ws >> ident; // 'window_geometry' - *is[i] >> t >> t >> t >> t; - } + char c; + string title; - if (glvis_command->WindowGeometry(x, y, w, h)) - { - goto comm_terminate; - } - } - else if (ident == "window_title") - { - char c; - string title; + // read the opening char + *is[0] >> ws >> c; + // use the opening char as termination as well + getline(*is[0], title, c); - // read the opening char - *is[0] >> ws >> c; - // use the opening char as termination as well - getline(*is[0], title, c); + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'window_title' + *is[i] >> ws >> c; + getline(*is[i], ident, c); + } - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'window_title' - *is[i] >> ws >> c; - getline(*is[i], ident, c); + if (glvis_command->WindowTitle(title.c_str())) + { + goto comm_terminate; + } } - - if (glvis_command->WindowTitle(title.c_str())) + break; + case Command::PlotCaption: { - goto comm_terminate; - } - } - else if (ident == "plot_caption") - { - char c; - string caption; + char c; + string caption; - // read the opening char - *is[0] >> ws >> c; - // use the opening char as termination as well - getline(*is[0], caption, c); + // read the opening char + *is[0] >> ws >> c; + // use the opening char as termination as well + getline(*is[0], caption, c); - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'plot_caption' - *is[i] >> ws >> c; - getline(*is[i], ident, c); + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'plot_caption' + *is[i] >> ws >> c; + getline(*is[i], ident, c); + } + + if (glvis_command->PlotCaption(caption.c_str())) + { + goto comm_terminate; + } } + break; + case Command::AxisLabels: + { + char c; + string label_x, label_y, label_z; + + // read the opening char + *is[0] >> ws >> c; + // use the opening char as termination as well + getline(*is[0], label_x, c); + *is[0] >> ws >> c; + getline(*is[0], label_y, c); + *is[0] >> ws >> c; + getline(*is[0], label_z, c); + + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'axis_label' + *is[i] >> ws >> c; + getline(*is[i], ident, c); + *is[i] >> ws >> c; + getline(*is[i], ident, c); + *is[i] >> ws >> c; + getline(*is[i], ident, c); + } - if (glvis_command->PlotCaption(caption.c_str())) - { - goto comm_terminate; + if (glvis_command->AxisLabels(label_x.c_str(), + label_y.c_str(), + label_z.c_str())) + { + goto comm_terminate; + } } - } - else if (ident == "axis_labels") - { - char c; - string label_x, label_y, label_z; - - // read the opening char - *is[0] >> ws >> c; - // use the opening char as termination as well - getline(*is[0], label_x, c); - *is[0] >> ws >> c; - getline(*is[0], label_y, c); - *is[0] >> ws >> c; - getline(*is[0], label_z, c); - - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) + break; + case Command::Pause: { - *is[i] >> ws >> ident; // 'axis_label' - *is[i] >> ws >> c; - getline(*is[i], ident, c); - *is[i] >> ws >> c; - getline(*is[i], ident, c); - *is[i] >> ws >> c; - getline(*is[i], ident, c); - } + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'pause' + } - if (glvis_command->AxisLabels(label_x.c_str(), - label_y.c_str(), - label_z.c_str())) - { - goto comm_terminate; + if (glvis_command->Pause()) + { + goto comm_terminate; + } } - } - else if (ident == "pause") - { - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) + break; + case Command::View: { - *is[i] >> ws >> ident; // 'pause' - } + double theta, phi, a; - if (glvis_command->Pause()) - { - goto comm_terminate; - } - } - else if (ident == "view") - { - double theta, phi, a; + *is[0] >> theta >> phi; - *is[0] >> theta >> phi; + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'view' + *is[i] >> a >> a; + } - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'view' - *is[i] >> a >> a; + if (glvis_command->ViewAngles(theta, phi)) + { + goto comm_terminate; + } } - - if (glvis_command->ViewAngles(theta, phi)) + break; + case Command::Zoom: { - goto comm_terminate; - } - } - else if (ident == "zoom") - { - double factor, a; + double factor, a; - *is[0] >> factor; + *is[0] >> factor; - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'zoom' - *is[i] >> a; - } + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'zoom' + *is[i] >> a; + } - if (glvis_command->Zoom(factor)) - { - goto comm_terminate; + if (glvis_command->Zoom(factor)) + { + goto comm_terminate; + } } - } - else if (ident == "subdivisions") - { - int tot, bdr, a; - - *is[0] >> tot >> bdr; - - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) + break; + case Command::Subdivisions: { - *is[i] >> ws >> ident; // 'subdivisions' - *is[i] >> a >> a; - } + int tot, bdr, a; - if (glvis_command->Subdivisions(tot, bdr)) - { - goto comm_terminate; - } - } - else if (ident == "valuerange") - { - double minv, maxv, a; + *is[0] >> tot >> bdr; - *is[0] >> minv >> maxv; + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'subdivisions' + *is[i] >> a >> a; + } - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'valuerange' - *is[i] >> a >> a; + if (glvis_command->Subdivisions(tot, bdr)) + { + goto comm_terminate; + } } - - if (glvis_command->ValueRange(minv, maxv)) + break; + case Command::Valuerange: { - goto comm_terminate; - } - } - else if (ident == "levellines") - { - double minv, maxv, a; - int num, b; + double minv, maxv, a; - *is[0] >> minv >> maxv >> num; + *is[0] >> minv >> maxv; - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'levellines' - *is[i] >> a >> a >> b; - } + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'valuerange' + *is[i] >> a >> a; + } - if (glvis_command->Levellines(minv, maxv, num)) - { - goto comm_terminate; + if (glvis_command->ValueRange(minv, maxv)) + { + goto comm_terminate; + } } - } - else if (ident == "axis_numberformat") - { - char c; - string formatting; + break; + case Command::Levellines: + { + double minv, maxv, a; + int num, b; - // read the opening char - *is[0] >> ws >> c; - // read formatting string & use c for termination - getline(*is[0], formatting, c); + *is[0] >> minv >> maxv >> num; - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'axis_numberformat' - *is[i] >> ws >> c; - getline(*is[i], ident, c); - } + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'levellines' + *is[i] >> a >> a >> b; + } - if (glvis_command->AxisNumberFormat(formatting)) - { - goto comm_terminate; + if (glvis_command->Levellines(minv, maxv, num)) + { + goto comm_terminate; + } } - } - else if (ident == "colorbar_numberformat") - { - char c; - string formatting; + break; + case Command::AxisNumberFormat: + { + char c; + string formatting; - // read the opening char - *is[0] >> ws >> c; - // read formatting string & use c for termination - getline(*is[0], formatting, c); + // read the opening char + *is[0] >> ws >> c; + // read formatting string & use c for termination + getline(*is[0], formatting, c); - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'colorbar_numberformat' - *is[i] >> ws >> c; - getline(*is[i], ident, c); - } + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'axis_numberformat' + *is[i] >> ws >> c; + getline(*is[i], ident, c); + } - if (glvis_command->ColorbarNumberFormat(formatting)) - { - goto comm_terminate; + if (glvis_command->AxisNumberFormat(formatting)) + { + goto comm_terminate; + } } - } - else if (ident == "shading") - { - string shd; + break; + case Command::ColorbarNumberFormat: + { + char c; + string formatting; - *is[0] >> ws >> shd; + // read the opening char + *is[0] >> ws >> c; + // read formatting string & use c for termination + getline(*is[0], formatting, c); - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'shading' - *is[i] >> ws >> ident; - } + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'colorbar_numberformat' + *is[i] >> ws >> c; + getline(*is[i], ident, c); + } - if (glvis_command->SetShading(shd.c_str())) - { - goto comm_terminate; + if (glvis_command->ColorbarNumberFormat(formatting)) + { + goto comm_terminate; + } } - } - else if (ident == "viewcenter") - { - double x, y, a; + break; + case Command::Shading: + { + string shd; - *is[0] >> x >> y; + *is[0] >> ws >> shd; - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'viewcenter' - *is[i] >> a >> a; - } + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'shading' + *is[i] >> ws >> ident; + } - if (glvis_command->ViewCenter(x, y)) - { - goto comm_terminate; + if (glvis_command->SetShading(shd.c_str())) + { + goto comm_terminate; + } } - } - else if (ident == "autoscale") - { - string mode; + break; + case Command::Viewcenter: + { + double x, y, a; - *is[0] >> ws >> mode; + *is[0] >> x >> y; - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'autoscale' - *is[i] >> ws >> ident; - } + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'viewcenter' + *is[i] >> a >> a; + } - if (glvis_command->Autoscale(mode.c_str())) - { - goto comm_terminate; + if (glvis_command->ViewCenter(x, y)) + { + goto comm_terminate; + } } - } - else if (ident == "palette") - { - int pal, a; + break; + case Command::Autoscale: + { + string mode; - *is[0] >> pal; + *is[0] >> ws >> mode; - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'palette' - *is[i] >> a; - } + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'autoscale' + *is[i] >> ws >> ident; + } - if (glvis_command->Palette(pal)) - { - goto comm_terminate; + if (glvis_command->Autoscale(mode.c_str())) + { + goto comm_terminate; + } } - } - else if (ident == "palette_repeat") - { - int n, a; + break; + case Command::Palette: + { + int pal, a; - *is[0] >> n; + *is[0] >> pal; - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'palette_repeat' - *is[i] >> a; - } + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'palette' + *is[i] >> a; + } - if (glvis_command->PaletteRepeat(n)) - { - goto comm_terminate; + if (glvis_command->Palette(pal)) + { + goto comm_terminate; + } } - } - else if (ident == "camera") - { - double cam[9], a; - - for (int i = 0; i < 9; i++) + break; + case Command::PaletteRepeat: { - *is[0] >> cam[i]; - } + int n, a; - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'camera' - for (int j = 0; j < 9; j++) + *is[0] >> n; + + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) { + *is[i] >> ws >> ident; // 'palette_repeat' *is[i] >> a; } - } - if (glvis_command->Camera(cam)) - { - goto comm_terminate; + if (glvis_command->PaletteRepeat(n)) + { + goto comm_terminate; + } } - } - else if (ident == "autopause") - { - string mode; + break; + case Command::Camera: + { + double cam[9], a; - *is[0] >> ws >> mode; + for (int i = 0; i < 9; i++) + { + *is[0] >> cam[i]; + } - // all processors sent the command - for (size_t i = 1; i < is.size(); i++) - { - *is[i] >> ws >> ident; // 'autopause' - *is[i] >> ws >> ident; - } + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'camera' + for (int j = 0; j < 9; j++) + { + *is[i] >> a; + } + } - if (glvis_command->Autopause(mode.c_str())) + if (glvis_command->Camera(cam)) + { + goto comm_terminate; + } + } + break; + case Command::Autopause: { - goto comm_terminate; + string mode; + + *is[0] >> ws >> mode; + + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'autopause' + *is[i] >> ws >> ident; + } + + if (glvis_command->Autopause(mode.c_str())) + { + goto comm_terminate; + } } - } - else - { - cout << "Stream: unknown command: " << ident << endl; + break; + default: + break; } } diff --git a/lib/threads.hpp b/lib/threads.hpp index 78c1649d..6d31d11b 100644 --- a/lib/threads.hpp +++ b/lib/threads.hpp @@ -163,6 +163,8 @@ class communication_thread // signal for thread cancellation std::atomic<bool> terminate_thread {false}; + static void init_commands(); + static void print_commands(); void execute(); public: From 3d658d8f3092313b66e60f4643180ff2e46a91e7 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 6 May 2025 02:16:04 -0700 Subject: [PATCH 19/65] Fixed confused fix_elem_orient and save_coloring in stream_reader. --- lib/stream_reader.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/stream_reader.cpp b/lib/stream_reader.cpp index 9fa45538..d73785b3 100644 --- a/lib/stream_reader.cpp +++ b/lib/stream_reader.cpp @@ -23,13 +23,13 @@ int StreamReader::ReadStream( if (data_type == "fem2d_data") { data.type = DataState::FieldType::SCALAR; - data.SetMesh(new Mesh(is, 0, 0, data.save_coloring)); + data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); data.sol.Load(is, data.mesh->GetNV()); } else if (data_type == "vfem2d_data" || data_type == "vfem2d_data_keys") { data.type = DataState::FieldType::VECTOR; - data.SetMesh(new Mesh(is, 0, 0, data.save_coloring)); + data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); data.solu.Load(is, data.mesh->GetNV()); data.solv.Load(is, data.mesh->GetNV()); if (data_type == "vfem2d_data_keys") @@ -40,13 +40,13 @@ int StreamReader::ReadStream( else if (data_type == "fem3d_data") { data.type = DataState::FieldType::SCALAR; - data.SetMesh(new Mesh(is, 0, 0, data.save_coloring)); + data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); data.sol.Load(is, data.mesh->GetNV()); } else if (data_type == "vfem3d_data" || data_type == "vfem3d_data_keys") { data.type = DataState::FieldType::VECTOR; - data.SetMesh(new Mesh(is, 0, 0, data.save_coloring)); + data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); data.solu.Load(is, data.mesh->GetNV()); data.solv.Load(is, data.mesh->GetNV()); data.solw.Load(is, data.mesh->GetNV()); @@ -57,7 +57,7 @@ int StreamReader::ReadStream( } else if (data_type == "fem2d_gf_data" || data_type == "fem2d_gf_data_keys") { - data.SetMesh(new Mesh(is, 1, 0, data.save_coloring)); + data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); data.SetGridFunction(new GridFunction(data.mesh.get(), is)); if (data_type == "fem2d_gf_data_keys") { @@ -66,7 +66,7 @@ int StreamReader::ReadStream( } else if (data_type == "vfem2d_gf_data" || data_type == "vfem2d_gf_data_keys") { - data.SetMesh(new Mesh(is, 1, 0, data.save_coloring)); + data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); data.SetGridFunction(new GridFunction(data.mesh.get(), is)); if (data_type == "vfem2d_gf_data_keys") { @@ -75,7 +75,7 @@ int StreamReader::ReadStream( } else if (data_type == "fem3d_gf_data" || data_type == "fem3d_gf_data_keys") { - data.SetMesh(new Mesh(is, 1, 0, data.save_coloring)); + data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); data.SetGridFunction(new GridFunction(data.mesh.get(), is)); if (data_type == "fem3d_gf_data_keys") { @@ -84,7 +84,7 @@ int StreamReader::ReadStream( } else if (data_type == "vfem3d_gf_data" || data_type == "vfem3d_gf_data_keys") { - data.SetMesh(new Mesh(is, 1, 0, data.save_coloring)); + data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); data.SetGridFunction(new GridFunction(data.mesh.get(), is)); if (data_type == "vfem3d_gf_data_keys") { @@ -93,18 +93,18 @@ int StreamReader::ReadStream( } else if (data_type == "solution") { - data.SetMesh(new Mesh(is, 1, 0, data.save_coloring)); + data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); data.SetGridFunction(new GridFunction(data.mesh.get(), is)); } else if (data_type == "quadrature") { - data.SetMesh(new Mesh(is, 1, 0, data.save_coloring)); + data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); data.SetQuadFunction(new QuadratureFunction(data.mesh.get(), is)); data.SetQuadSolution(); } else if (data_type == "mesh") { - data.SetMesh(new Mesh(is, 1, 0, data.save_coloring)); + data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); data.SetMeshSolution(); } else if (data_type == "raw_scalar_2d") @@ -200,11 +200,11 @@ int StreamReader::ReadStream( if (mesh_type == 1) { - data.mesh->FinalizeTriMesh(1, 0, data.save_coloring); + data.mesh->FinalizeTriMesh(1, 0, data.fix_elem_orient); } else if (mesh_type == 2) { - data.mesh->FinalizeQuadMesh(1, 0, data.save_coloring); + data.mesh->FinalizeQuadMesh(1, 0, data.fix_elem_orient); } else { @@ -256,7 +256,7 @@ int StreamReader::ReadStreams(const StreamCollection &input_streams) #ifdef GLVIS_DEBUG cout << " type " << data_type << " ... " << flush; #endif - mesh_array[p] = new Mesh(isock, 1, 0, data.save_coloring); + mesh_array[p] = new Mesh(isock, 1, 0, data.fix_elem_orient); if (!data.keep_attr) { // set element and boundary attributes to proc+1 From 25bccc965485f02134851f596adbbab2c90b3efb Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 6 May 2025 03:27:03 -0700 Subject: [PATCH 20/65] Unified loading of solutions from stream. --- lib/threads.cpp | 110 +++++++++--------------------------------------- 1 file changed, 20 insertions(+), 90 deletions(-) diff --git a/lib/threads.cpp b/lib/threads.cpp index fdad95fe..4071adde 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -939,47 +939,18 @@ void communication_thread::execute() case Command::Quadrature: case Command::Parallel: { - bool fix_elem_orient = glvis_command->FixElementOrientations(); bool done = false; DataState tmp; + tmp.fix_elem_orient = glvis_command->FixElementOrientations(); + tmp.keep_attr = glvis_command->KeepAttrib(); + StreamReader reader(tmp); switch (cmd) { case Command::Mesh: - { - tmp.SetMesh(new Mesh(*is[0], 1, 0, fix_elem_orient)); - if (!(*is[0])) - { - done = true; - break; - } - tmp.SetGridFunction(NULL); - } - break; case Command::Solution: - { - tmp.SetMesh(new Mesh(*is[0], 1, 0, fix_elem_orient)); - if (!(*is[0])) - { - done = true; - break; - } - tmp.SetGridFunction(new GridFunction(tmp.mesh.get(), *is[0])); - if (!(*is[0])) - { - done = true; - break; - } - } - break; case Command::Quadrature: { - tmp.SetMesh(new Mesh(*is[0], 1, 0, fix_elem_orient)); - if (!(*is[0])) - { - done = true; - break; - } - tmp.SetQuadFunction(new QuadratureFunction(tmp.mesh.get(), *is[0])); + reader.ReadStream(*is[0], ident); if (!(*is[0])) { done = true; @@ -989,11 +960,7 @@ void communication_thread::execute() break; case Command::Parallel: { - std::vector<Mesh*> mesh_array; - std::vector<GridFunction*> gf_array; - std::vector<QuadratureFunction*> qf_array; - int proc, nproc, np = 0; - bool keep_attr = glvis_command->KeepAttrib(); + unsigned int proc, nproc, np = 0; do { istream &isock = *is[np]; @@ -1002,34 +969,17 @@ void communication_thread::execute() cout << "connection[" << np << "]: parallel " << nproc << ' ' << proc << endl; #endif - isock >> ident >> ws; - mesh_array.resize(nproc); - mesh_array[proc] = new Mesh(isock, 1, 0, fix_elem_orient); - if (!keep_attr) - { - // set element and boundary attributes to proc+1 - for (int i = 0; i < mesh_array[proc]->GetNE(); i++) - { - mesh_array[proc]->GetElement(i)->SetAttribute(proc+1); - } - for (int i = 0; i < mesh_array[proc]->GetNBE(); i++) - { - mesh_array[proc]->GetBdrElement(i)->SetAttribute(proc+1); - } - } - if (ident == "solution") + if (nproc != is.size()) { - gf_array.resize(nproc); - gf_array[proc] = new GridFunction(mesh_array[proc], isock); + cout << "Unexpected number of processors: " << nproc + << ", expected: " << is.size() << endl; + mfem_error(); } - else if (ident == "quadrature") + if (proc >= nproc) { - qf_array.resize(nproc); - qf_array[proc] = new QuadratureFunction(mesh_array[proc], isock); - } - else - { - cout << "Stream: unknown command: " << ident << endl; + cout << "Invalid processor rank: " << proc + << ", number of processors: " << nproc << endl; + mfem_error(); } np++; if (np == nproc) @@ -1037,34 +987,16 @@ void communication_thread::execute() break; } *is[np] >> ident >> ws; // "parallel" - } - while (1); - - tmp.SetMesh(new Mesh(mesh_array.data(), nproc)); - if (gf_array.size() > 0) - { - tmp.SetGridFunction(new GridFunction(tmp.mesh.get(), gf_array.data(), nproc)); - } - else if (qf_array.size() > 0) - { - tmp.SetQuadFunction(qf_array); - } - - for (int p = 0; p < nproc; p++) - { - if (gf_array.size() > 0) + if (ident != "parallel") { - delete gf_array[nproc-1-p]; + cout << "Expected keyword \"parallel\", got \"" << ident + << '"' << endl; + mfem_error(); } - if (qf_array.size() > 0) - { - delete qf_array[nproc-1-p]; - } - delete mesh_array[nproc-1-p]; } - gf_array.clear(); - qf_array.clear(); - mesh_array.clear(); + while (1); + + reader.ReadStreams(is); } break; default: @@ -1074,8 +1006,6 @@ void communication_thread::execute() // cout << "Stream: new solution" << endl; - tmp.ExtrudeMeshAndSolution(); - if (glvis_command->NewMeshAndSolution(std::move(tmp))) { goto comm_terminate; From 451066337af2b4cc1d7cbccc1c9cc09a67a98e3d Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 6 May 2025 04:41:23 -0700 Subject: [PATCH 21/65] Changed StreamReader to commands list. --- lib/stream_reader.cpp | 426 ++++++++++++++++++++++++------------------ lib/stream_reader.hpp | 5 +- 2 files changed, 244 insertions(+), 187 deletions(-) diff --git a/lib/stream_reader.cpp b/lib/stream_reader.cpp index d73785b3..4a6416d5 100644 --- a/lib/stream_reader.cpp +++ b/lib/stream_reader.cpp @@ -11,222 +11,276 @@ #include "stream_reader.hpp" +#include <vector> +#include <algorithm> + using namespace std; using namespace mfem; -int StreamReader::ReadStream( - istream &is, const string &data_type) +enum class Command { - data.SetMesh(NULL); - data.keys.clear(); + Mesh, + Solution, + Quadrature, + Fem2D, + VFem2D, + VFem2D_keys, + Fem3D, + VFem3D, + VFem3D_keys, + Fem2D_GF, + Fem2D_GF_keys, + VFem2D_GF, + VFem2D_GF_keys, + Fem3D_GF, + Fem3D_GF_keys, + VFem3D_GF, + VFem3D_GF_keys, + RawScalar2D, + //---------- + Max +}; - if (data_type == "fem2d_data") - { - data.type = DataState::FieldType::SCALAR; - data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); - data.sol.Load(is, data.mesh->GetNV()); - } - else if (data_type == "vfem2d_data" || data_type == "vfem2d_data_keys") - { - data.type = DataState::FieldType::VECTOR; - data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); - data.solu.Load(is, data.mesh->GetNV()); - data.solv.Load(is, data.mesh->GetNV()); - if (data_type == "vfem2d_data_keys") - { - is >> data.keys; - } - } - else if (data_type == "fem3d_data") - { - data.type = DataState::FieldType::SCALAR; - data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); - data.sol.Load(is, data.mesh->GetNV()); - } - else if (data_type == "vfem3d_data" || data_type == "vfem3d_data_keys") - { - data.type = DataState::FieldType::VECTOR; - data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); - data.solu.Load(is, data.mesh->GetNV()); - data.solv.Load(is, data.mesh->GetNV()); - data.solw.Load(is, data.mesh->GetNV()); - if (data_type == "vfem3d_data_keys") - { - is >> data.keys; - } - } - else if (data_type == "fem2d_gf_data" || data_type == "fem2d_gf_data_keys") - { - data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); - data.SetGridFunction(new GridFunction(data.mesh.get(), is)); - if (data_type == "fem2d_gf_data_keys") - { - is >> data.keys; - } - } - else if (data_type == "vfem2d_gf_data" || data_type == "vfem2d_gf_data_keys") - { - data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); - data.SetGridFunction(new GridFunction(data.mesh.get(), is)); - if (data_type == "vfem2d_gf_data_keys") - { - is >> data.keys; - } - } - else if (data_type == "fem3d_gf_data" || data_type == "fem3d_gf_data_keys") - { - data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); - data.SetGridFunction(new GridFunction(data.mesh.get(), is)); - if (data_type == "fem3d_gf_data_keys") - { - is >> data.keys; - } - } - else if (data_type == "vfem3d_gf_data" || data_type == "vfem3d_gf_data_keys") - { - data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); - data.SetGridFunction(new GridFunction(data.mesh.get(), is)); - if (data_type == "vfem3d_gf_data_keys") - { - is >> data.keys; - } - } - else if (data_type == "solution") +struct CmdItem +{ + const char *keyword; + bool keys; + const char *params; + const char *desc; + + bool operator==(const string &key) const { return key == keyword; } +}; + +static vector<CmdItem> commands; + +StreamReader::StreamReader(DataState &data_) + : data(data_) +{ + if (commands.empty()) { - data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); - data.SetGridFunction(new GridFunction(data.mesh.get(), is)); + InitCommands(); } - else if (data_type == "quadrature") +} + +void StreamReader::InitCommands() +{ + commands.resize((size_t)Command::Max); + + commands[(size_t)Command::Mesh] = {"mesh", false, "<mesh>", "Visualize the mesh."}; + commands[(size_t)Command::Solution] = {"solution", false, "<mesh> <solution>", "Visualize the solution."}; + commands[(size_t)Command::Quadrature] = {"quadrature", false, "<mesh> <quadrature>", "Visualize the quadrature."}; + commands[(size_t)Command::Fem2D] = {"fem2d_data", false, "<mesh> <data>", "Visualize the 2D scalar data."}; + commands[(size_t)Command::VFem2D] = {"vfem2d_data", false, "<mesh> <data_x> <data_y>", "Visualize the 2D vector data."}; + commands[(size_t)Command::VFem2D_keys] = {"vfem2d_data_keys", true, "<mesh> <data_x> <data_y> <keys>", "Visualize the 2D vector data and apply control keys."}; + commands[(size_t)Command::Fem3D] = {"fem3d_data", false, "<mesh> <data>", "Visualize the 3D scalar data."}; + commands[(size_t)Command::VFem3D] = {"vfem3d_data", false, "<mesh> <data_x> <data_y> <data_z>", "Visualize the 3D vector data."}; + commands[(size_t)Command::VFem3D_keys] = {"vfem3d_data_keys", true, "<mesh> <data_x> <data_y> <data_z> <keys>", "Visualize the 3D vector data and apply control keys."}; + commands[(size_t)Command::Fem2D_GF] = {"fem2d_gf_data", false, "<mesh> <solution>", "Visualize the 2D scalar grid function."}; + commands[(size_t)Command::Fem2D_GF_keys] = {"fem2d_gf_data_keys", true, "<mesh> <solution> <keys>", "Visualize the 2D scalar grid function and apply control keys."}; + commands[(size_t)Command::VFem2D_GF] = {"vfem2d_gf_data", false, "<mesh> <solution>", "Visualize the 2D vector grid function."}; + commands[(size_t)Command::VFem2D_GF_keys] = {"vfem2d_gf_data_keys", true, "<mesh> <solution> <keys>", "Visualize the 2D vector grid function and apply control keys."}; + commands[(size_t)Command::Fem3D_GF] = {"fem3d_gf_data", false, "<mesh> <solution>", "Visualize the 3D scalar grid function."}; + commands[(size_t)Command::Fem3D_GF_keys] = {"fem3d_gf_data_keys", true, "<mesh> <solution> <keys>", "Visualize the 3D scalar grid function and apply control keys."}; + commands[(size_t)Command::VFem3D_GF] = {"vfem3d_gf_data", false, "<mesh> <solution>", "Visualize the 3D vector grid function."}; + commands[(size_t)Command::VFem3D_GF_keys] = {"vfem3d_gf_data_keys", true, "<mesh> <solution> <keys>", "Visualize the 3D vector grid function and apply control keys."}; + commands[(size_t)Command::RawScalar2D] = {"raw_scalar_2d", false, "<data>", "Visualize the 2D scalar data (see stream_reader.cpp)."}; +} + +void StreamReader::PrintCommands() +{ + cout << "Available commands are:" << endl; + + for (const CmdItem &ci : commands) { - data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); - data.SetQuadFunction(new QuadratureFunction(data.mesh.get(), is)); - data.SetQuadSolution(); + cout << "\t" << ci.keyword << " " << ci.params << " - " << ci.desc << endl; } - else if (data_type == "mesh") +} + +int StreamReader::ReadStream( + istream &is, const string &data_type) +{ + data.SetMesh(NULL); + data.keys.clear(); + + auto it = find(commands.begin(), commands.end(), data_type); + if (it == commands.end()) { - data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); - data.SetMeshSolution(); + cerr << "Unknown data format " << data_type << endl; + PrintCommands(); + return 1; } - else if (data_type == "raw_scalar_2d") + + Command cmd = (Command)(it - commands.begin()); + switch (cmd) { - Array<Array<double> *> vertices; - Array<Array<int> *> elements; - Array<int> elem_types; - string ident; - int num_patches, num_vert, num_elem, n; - is >> ws >> ident; // 'patches' - is >> num_patches; - // cout << ident << ' ' << num_patches << endl; - vertices.SetSize(num_patches); - vertices = NULL; - elements.SetSize(num_patches); - elements = NULL; - elem_types.SetSize(num_patches); - elem_types = 0; - int tot_num_vert = 0; - int tot_num_elem = 0; - int mesh_type = 0; - for (int i = 0; i < num_patches; i++) + case Command::Fem2D: + data.type = DataState::FieldType::SCALAR; + data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); + data.sol.Load(is, data.mesh->GetNV()); + break; + case Command::VFem2D: + case Command::VFem2D_keys: + data.type = DataState::FieldType::VECTOR; + data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); + data.solu.Load(is, data.mesh->GetNV()); + data.solv.Load(is, data.mesh->GetNV()); + break; + case Command::Fem3D: + data.type = DataState::FieldType::SCALAR; + data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); + data.sol.Load(is, data.mesh->GetNV()); + break; + case Command::VFem3D: + case Command::VFem3D_keys: + data.type = DataState::FieldType::VECTOR; + data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); + data.solu.Load(is, data.mesh->GetNV()); + data.solv.Load(is, data.mesh->GetNV()); + data.solw.Load(is, data.mesh->GetNV()); + break; + case Command::Fem2D_GF: + case Command::Fem2D_GF_keys: + case Command::VFem2D_GF: + case Command::VFem2D_GF_keys: + case Command::Fem3D_GF: + case Command::Fem3D_GF_keys: + case Command::VFem3D_GF: + case Command::VFem3D_GF_keys: + case Command::Solution: + data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); + data.SetGridFunction(new GridFunction(data.mesh.get(), is)); + break; + case Command::Quadrature: + data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); + data.SetQuadFunction(new QuadratureFunction(data.mesh.get(), is)); + break; + case Command::Mesh: + data.SetMesh(new Mesh(is, 1, 0, data.fix_elem_orient)); + data.SetMeshSolution(); + break; + case Command::RawScalar2D: { - is >> ws >> ident; // 'vertices' - is >> num_vert; - // cout << '\n' << ident << ' ' << num_vert << endl; - // read vertices in the format: x y z nx ny nz - vertices[i] = new Array<double>(6*num_vert); - Array<double> &verts = *vertices[i]; - for (int j = 0; j < verts.Size(); j++) + Array<Array<double> *> vertices; + Array<Array<int> *> elements; + Array<int> elem_types; + string ident; + int num_patches, num_vert, num_elem, n; + is >> ws >> ident; // 'patches' + is >> num_patches; + // cout << ident << ' ' << num_patches << endl; + vertices.SetSize(num_patches); + vertices = NULL; + elements.SetSize(num_patches); + elements = NULL; + elem_types.SetSize(num_patches); + elem_types = 0; + int tot_num_vert = 0; + int tot_num_elem = 0; + int mesh_type = 0; + for (int i = 0; i < num_patches; i++) { - is >> verts[j]; + is >> ws >> ident; // 'vertices' + is >> num_vert; + // cout << '\n' << ident << ' ' << num_vert << endl; + // read vertices in the format: x y z nx ny nz + vertices[i] = new Array<double>(6*num_vert); + Array<double> &verts = *vertices[i]; + for (int j = 0; j < verts.Size(); j++) + { + is >> verts[j]; + } + + is >> ws >> ident; // 'triangles' or 'quads' + if (ident == "triangles") + { + n = 3, mesh_type |= 1; + } + else + { + n = 4, mesh_type |= 2; + } + elem_types[i] = n; + is >> num_elem; + // cout << ident << ' ' << num_elem << endl; + elements[i] = new Array<int>(n*num_elem); + Array<int> &elems = *elements[i]; + for (int j = 0; j < elems.Size(); j++) + { + is >> elems[j]; + elems[j] += tot_num_vert; + } + tot_num_vert += num_vert; + tot_num_elem += num_elem; } - is >> ws >> ident; // 'triangles' or 'quads' - if (ident == "triangles") + data.SetMesh(new Mesh(2, tot_num_vert, tot_num_elem, 0)); + data.sol.SetSize(tot_num_vert); + data.normals.SetSize(3*tot_num_vert); + + int v_off = 0; + for (int i = 0; i < num_patches; i++) { - n = 3, mesh_type |= 1; + Array<double> &verts = *vertices[i]; + num_vert = verts.Size()/6; + for (int j = 0; j < num_vert; j++) + { + data.mesh->AddVertex(&verts[6*j]); + data.sol(v_off) = verts[6*j+2]; + data.normals(3*v_off+0) = verts[6*j+3]; + data.normals(3*v_off+1) = verts[6*j+4]; + data.normals(3*v_off+2) = verts[6*j+5]; + v_off++; + } + + n = elem_types[i]; + Array<int> &elems = *elements[i]; + num_elem = elems.Size()/n; + // int attr = 1; + int attr = i + 1; + if (n == 3) + for (int j = 0; j < num_elem; j++) + { + data.mesh->AddTriangle(&elems[3*j], attr); + } + else + for (int j = 0; j < num_elem; j++) + { + data.mesh->AddQuad(&elems[4*j], attr); + } } - else + + if (mesh_type == 1) { - n = 4, mesh_type |= 2; + data.mesh->FinalizeTriMesh(1, 0, data.fix_elem_orient); } - elem_types[i] = n; - is >> num_elem; - // cout << ident << ' ' << num_elem << endl; - elements[i] = new Array<int>(n*num_elem); - Array<int> &elems = *elements[i]; - for (int j = 0; j < elems.Size(); j++) + else if (mesh_type == 2) { - is >> elems[j]; - elems[j] += tot_num_vert; + data.mesh->FinalizeQuadMesh(1, 0, data.fix_elem_orient); } - tot_num_vert += num_vert; - tot_num_elem += num_elem; - } - - data.SetMesh(new Mesh(2, tot_num_vert, tot_num_elem, 0)); - data.sol.SetSize(tot_num_vert); - data.normals.SetSize(3*tot_num_vert); - - int v_off = 0; - for (int i = 0; i < num_patches; i++) - { - Array<double> &verts = *vertices[i]; - num_vert = verts.Size()/6; - for (int j = 0; j < num_vert; j++) + else { - data.mesh->AddVertex(&verts[6*j]); - data.sol(v_off) = verts[6*j+2]; - data.normals(3*v_off+0) = verts[6*j+3]; - data.normals(3*v_off+1) = verts[6*j+4]; - data.normals(3*v_off+2) = verts[6*j+5]; - v_off++; + mfem_error("Input data contains mixture of triangles and quads!"); } - n = elem_types[i]; - Array<int> &elems = *elements[i]; - num_elem = elems.Size()/n; - // int attr = 1; - int attr = i + 1; - if (n == 3) - for (int j = 0; j < num_elem; j++) - { - data.mesh->AddTriangle(&elems[3*j], attr); - } - else - for (int j = 0; j < num_elem; j++) - { - data.mesh->AddQuad(&elems[4*j], attr); - } - } - - if (mesh_type == 1) - { - data.mesh->FinalizeTriMesh(1, 0, data.fix_elem_orient); - } - else if (mesh_type == 2) - { - data.mesh->FinalizeQuadMesh(1, 0, data.fix_elem_orient); - } - else - { - mfem_error("Input data contains mixture of triangles and quads!"); - } + data.mesh->GenerateBoundaryElements(); - data.mesh->GenerateBoundaryElements(); + for (int i = num_patches; i > 0; ) + { + i--; + delete elements[i]; + delete vertices[i]; + } - for (int i = num_patches; i > 0; ) - { - i--; - delete elements[i]; - delete vertices[i]; + data.type = DataState::FieldType::SCALAR; } - - data.type = DataState::FieldType::SCALAR; + break; + default: + break; } - else + + if (commands[(size_t)cmd].keys) { - cerr << "Unknown data format" << endl; - cerr << data_type << endl; - return 1; + is >> data.keys; } data.ExtrudeMeshAndSolution(); diff --git a/lib/stream_reader.hpp b/lib/stream_reader.hpp index eb9606f0..847c268d 100644 --- a/lib/stream_reader.hpp +++ b/lib/stream_reader.hpp @@ -25,8 +25,11 @@ class StreamReader { DataState &data; + static void InitCommands(); + static void PrintCommands(); + public: - StreamReader(DataState &data_) : data(data_) { } + StreamReader(DataState &data_); /// Read the content of an input stream (e.g. from socket/file) int ReadStream(std::istream &is, const std::string &data_type); From 2df9cc9a5b9e83285479bd2dfc1b60645dd55e38 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 6 May 2025 04:49:25 -0700 Subject: [PATCH 22/65] Fixed script handling of data coll meshes and improved code safety for commands enums. --- lib/script_controller.cpp | 3 ++- lib/stream_reader.cpp | 2 +- lib/threads.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index 56e60a76..0decf3d8 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -396,6 +396,7 @@ void ScriptController::ExecuteScriptCommand() case Command::ParSolution: case Command::Quadrature: case Command::ParQuadrature: + case Command::DataCollMesh: case Command::DataCollField: case Command::DataCollQuad: { @@ -804,7 +805,7 @@ void ScriptController::ExecuteScriptCommand() MyExpose(); } break; - default: + case Command::Max: //dummy break; } diff --git a/lib/stream_reader.cpp b/lib/stream_reader.cpp index 4a6416d5..0dc60f4a 100644 --- a/lib/stream_reader.cpp +++ b/lib/stream_reader.cpp @@ -274,7 +274,7 @@ int StreamReader::ReadStream( data.type = DataState::FieldType::SCALAR; } break; - default: + case Command::Max: //dummy break; } diff --git a/lib/threads.cpp b/lib/threads.cpp index 4071adde..8f9f32e4 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -1467,7 +1467,7 @@ void communication_thread::execute() } } break; - default: + case Command::Max: //dummy break; } } From 94add8b5c9e3f018986688fc4f23290a86412ac9 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 6 May 2025 05:18:57 -0700 Subject: [PATCH 23/65] Unified handling of solutions in streams. --- lib/stream_reader.cpp | 11 ++++ lib/stream_reader.hpp | 8 ++- lib/threads.cpp | 123 +++++++++++++++++++----------------------- 3 files changed, 74 insertions(+), 68 deletions(-) diff --git a/lib/stream_reader.cpp b/lib/stream_reader.cpp index 0dc60f4a..2b528c21 100644 --- a/lib/stream_reader.cpp +++ b/lib/stream_reader.cpp @@ -96,6 +96,17 @@ void StreamReader::PrintCommands() } } +bool StreamReader::SupportsDataType(const string &data_type) +{ + if (commands.empty()) + { + InitCommands(); + } + + auto it = find(commands.begin(), commands.end(), data_type); + return it != commands.end(); +} + int StreamReader::ReadStream( istream &is, const string &data_type) { diff --git a/lib/stream_reader.hpp b/lib/stream_reader.hpp index 847c268d..2fdecaab 100644 --- a/lib/stream_reader.hpp +++ b/lib/stream_reader.hpp @@ -26,11 +26,17 @@ class StreamReader DataState &data; static void InitCommands(); - static void PrintCommands(); public: + StreamReader(DataState &data_); + /// Prints available commands + static void PrintCommands(); + + /// Tests if the data type is supported + static bool SupportsDataType(const std::string &data_type); + /// Read the content of an input stream (e.g. from socket/file) int ReadStream(std::istream &is, const std::string &data_type); diff --git a/lib/threads.cpp b/lib/threads.cpp index 8f9f32e4..e27ab24a 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -799,9 +799,6 @@ GLVisCommand::~GLVisCommand() enum class Command { - Mesh, - Solution, - Quadrature, Parallel, Screenshot, Viewcenter, @@ -871,9 +868,6 @@ void communication_thread::init_commands() { commands.resize((size_t)Command::Max); - commands[(size_t)Command::Mesh] = {"mesh", "<mesh>", "Visualize the mesh."}; - commands[(size_t)Command::Solution] = {"solution", "<mesh> <solution>", "Visualize the solution."}; - commands[(size_t)Command::Quadrature] = {"quadrature", "<mesh> <quadrature>", "Visualize the quadrature."}; commands[(size_t)Command::Parallel] = {"parallel", "<num proc> <proc>", "Prefix for distributed mesh/solution/quadrature."}; commands[(size_t)Command::Screenshot] = {"screenshot", "<file>", "Take a screenshot, saving it to the file."}; commands[(size_t)Command::Viewcenter] = {"viewcenter", "<x> <y>", "Change the viewcenter."}; @@ -901,7 +895,7 @@ void communication_thread::init_commands() void communication_thread::print_commands() { - cout << "Available commands are:" << endl; + StreamReader::PrintCommands(); for (const CmdItem &ci : commands) { @@ -923,6 +917,27 @@ void communication_thread::execute() break; } + // new solution handled by StreamReader + if (StreamReader::SupportsDataType(ident)) + { + DataState tmp; + tmp.fix_elem_orient = glvis_command->FixElementOrientations(); + StreamReader reader(tmp); + reader.ReadStream(*is[0], ident); + if (!(*is[0])) + { + break; + } + + // cout << "Stream: new solution" << endl; + + if (glvis_command->NewMeshAndSolution(std::move(tmp))) + { + goto comm_terminate; + } + continue; + } + auto it = find(commands.begin(), commands.end(), ident); if (it == commands.end()) { @@ -934,75 +949,49 @@ void communication_thread::execute() const Command cmd = (Command)(it - commands.begin()); switch (cmd) { - case Command::Mesh: - case Command::Solution: - case Command::Quadrature: case Command::Parallel: { - bool done = false; - DataState tmp; - tmp.fix_elem_orient = glvis_command->FixElementOrientations(); - tmp.keep_attr = glvis_command->KeepAttrib(); - StreamReader reader(tmp); - switch (cmd) + unsigned int proc, nproc, np = 0; + do { - case Command::Mesh: - case Command::Solution: - case Command::Quadrature: + istream &isock = *is[np]; + isock >> nproc >> proc >> ws; +#ifdef GLVIS_DEBUG + cout << "connection[" << np << "]: parallel " << nproc << ' ' + << proc << endl; +#endif + if (nproc != is.size()) { - reader.ReadStream(*is[0], ident); - if (!(*is[0])) - { - done = true; - break; - } + cout << "Unexpected number of processors: " << nproc + << ", expected: " << is.size() << endl; + mfem_error(); } - break; - case Command::Parallel: + if (proc >= nproc) { - unsigned int proc, nproc, np = 0; - do - { - istream &isock = *is[np]; - isock >> nproc >> proc >> ws; -#ifdef GLVIS_DEBUG - cout << "connection[" << np << "]: parallel " << nproc << ' ' - << proc << endl; -#endif - if (nproc != is.size()) - { - cout << "Unexpected number of processors: " << nproc - << ", expected: " << is.size() << endl; - mfem_error(); - } - if (proc >= nproc) - { - cout << "Invalid processor rank: " << proc - << ", number of processors: " << nproc << endl; - mfem_error(); - } - np++; - if (np == nproc) - { - break; - } - *is[np] >> ident >> ws; // "parallel" - if (ident != "parallel") - { - cout << "Expected keyword \"parallel\", got \"" << ident - << '"' << endl; - mfem_error(); - } - } - while (1); - - reader.ReadStreams(is); + cout << "Invalid processor rank: " << proc + << ", number of processors: " << nproc << endl; + mfem_error(); } - break; - default: + np++; + if (np == nproc) + { break; + } + *is[np] >> ident >> ws; // "parallel" + if (ident != "parallel") + { + cout << "Expected keyword \"parallel\", got \"" << ident + << '"' << endl; + mfem_error(); + } } - if (done) { break; } + while (1); + + DataState tmp; + tmp.fix_elem_orient = glvis_command->FixElementOrientations(); + tmp.keep_attr = glvis_command->KeepAttrib(); + StreamReader reader(tmp); + reader.ReadStreams(is); // cout << "Stream: new solution" << endl; From b2ffa5a12488d4298bf487e9d504a1216a063ffc Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 6 May 2025 05:45:13 -0700 Subject: [PATCH 24/65] Added handling of keys if bundled with data. --- lib/threads.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/threads.cpp b/lib/threads.cpp index e27ab24a..f8abec59 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -935,6 +935,13 @@ void communication_thread::execute() { goto comm_terminate; } + if (!tmp.keys.empty()) + { + if (glvis_command->KeyCommands(tmp.keys.c_str())) + { + goto comm_terminate; + } + } continue; } From 9f9502d4c70b8966d24c1e9ac5c1308a0830f52e Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 6 May 2025 07:12:53 -0700 Subject: [PATCH 25/65] Made command lists thread-safe. --- lib/script_controller.cpp | 111 +++++++++++++++++++------------------- lib/script_controller.hpp | 3 +- lib/stream_reader.cpp | 48 ++++++++--------- lib/stream_reader.hpp | 4 +- lib/threads.cpp | 80 ++++++++++++++------------- lib/threads.hpp | 1 - 6 files changed, 120 insertions(+), 127 deletions(-) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index 0decf3d8..2a238fd5 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -15,7 +15,7 @@ #include "stream_reader.hpp" #include "visual.hpp" -#include <vector> +#include <array> #include <algorithm> using namespace std; @@ -60,16 +60,63 @@ enum class Command Max }; -struct CmdItem +class ScriptCommands { - const char *keyword; - const char *params; - const char *desc; + struct CmdItem + { + const char *keyword; + const char *params; + const char *desc; + + bool operator==(const string &key) const { return key == keyword; } + }; + array<CmdItem,(size_t)Command::Max> commands; - bool operator==(const string &key) const { return key == keyword; } +public: + ScriptCommands(); + + array<CmdItem,(size_t)Command::Max>::const_iterator begin() const { return commands.begin(); } + array<CmdItem,(size_t)Command::Max>::const_iterator end() const { return commands.end(); } + const CmdItem& operator[](Command cmd) const { return commands[(size_t)cmd]; } }; +static const ScriptCommands commands; -static vector<CmdItem> commands; +ScriptCommands::ScriptCommands() +{ + commands[(size_t)Command::Mesh] = {"mesh", "<file>", "Visualize the mesh."}; + commands[(size_t)Command::Solution] = {"solution", "<mesh> <solution>", "Visualize the solution."}; + commands[(size_t)Command::ParSolution] = {"psolution", "<np> <mesh prefix> <keep attributes> <solution prefix>", "Visualize the distributed solution."}; + commands[(size_t)Command::Quadrature] = {"quadrature", "<mesh> <quadrature>", "Visualize the quadrature."}; + commands[(size_t)Command::ParQuadrature] = {"pquadrature", "<np> <mesh prefix> <keep attributes> <quadrature prefix>", "Visualize the distributed quadrature."}; + commands[(size_t)Command::DataCollMesh] = {"data_coll_mesh", "<type> <data coll>", "Visualize the mesh from data collection."}; + commands[(size_t)Command::DataCollField] = {"data_coll_field", "<type> <data coll> <field>", "Visualize the field from data collection."}; + commands[(size_t)Command::DataCollQuad] = {"data_coll_quad", "<type> <data coll> <quad>", "Visualize the Q-field from data collection."}; + commands[(size_t)Command::DataCollCycle] = {"data_coll_cycle", "<cycle>", "Preset the cycle of the data collection."}; + commands[(size_t)Command::DataCollProto] = {"data_coll_protocol", "<protocol>", "Preset the protocol of the data collection."}; + commands[(size_t)Command::Screenshot] = {"screenshot", "<file>", "Take a screenshot, saving it to the file."}; + commands[(size_t)Command::Viewcenter] = {"viewcenter", "<x> <y>", "Change the viewcenter."}; + commands[(size_t)Command::Perspective] = {"perspective", "<on/off>", "Turn on or off perspective projection."}; + commands[(size_t)Command::Light] = {"light", "<on/off>", "Turn on or off light."}; + commands[(size_t)Command::View] = {"view", "<theta> <phi>", "Change the solid angle of view."}; + commands[(size_t)Command::Zoom] = {"zoom", "<zoom>", "Change the zoom factor."}; + commands[(size_t)Command::Shading] = {"shading", "<flat/smooth/cool>", "Change the shading algorithm."}; + commands[(size_t)Command::Subdivisions] = {"subdivisions", "<times> <dummy>", "Change the refinement level."}; + commands[(size_t)Command::Valuerange] = {"valuerange", "<min> <max>", "Change the value range."}; + commands[(size_t)Command::Autoscale] = {"autoscale", "<off/on/value/mesh>", "Change the autoscale algorithm."}; + commands[(size_t)Command::Levellines] = {"levellines", "<min> <max> <num>", "Set the level lines."}; + commands[(size_t)Command::AxisNumberFormat] = {"axis_numberformat", "'<format>'", "Set the axis number format."}; + commands[(size_t)Command::ColorbarNumberFormat] = {"colorbar_numberformat", "'<format>'", "Set the colorbar number format."}; + commands[(size_t)Command::Window] = {"window", "<x> <y> <w> <h>", "Set the position and size of the window."}; + commands[(size_t)Command::Keys] = {"keys", "<keys>", "Send the control key sequence."}; + commands[(size_t)Command::Palette] = {"palette", "<index>", "Set the palette index."}; + commands[(size_t)Command::PaletteRepeat] = {"palette_repeat", "<times>", "Set the repetition of the palette."}; + commands[(size_t)Command::ToggleAttributes] = {"toggle_attributes", "<1/0> [[<1/0>] ...];", "Toggle visibility of the attributes."}; + commands[(size_t)Command::Rotmat] = {"rotmat", "<[0,0]> <[1,0]> ... <[3,3]>", "Set the rotation matrix."}; + commands[(size_t)Command::Camera] = {"camera", "<cam[0]> ... <cam[2]> <dir[0]> ... <dir[2]> <up[0]> ... <up[2]>", "Set the camera position, direction and upward vector."}; + commands[(size_t)Command::Scale] = {"scale", "<scale>", "Set the scaling factor."}; + commands[(size_t)Command::Translate] = {"translate", "<x> <y> <z>", "Set the translation coordinates."}; + commands[(size_t)Command::PlotCaption] = {"plot_caption", "'<caption>'", "Set the plot caption."}; +} int ScriptController::ScriptReadSolution(istream &scr, DataState &state) { @@ -290,50 +337,11 @@ int ScriptController::ScriptReadDataColl(istream &scr, DataState &state, return err_read; } -void ScriptController::InitCommands() -{ - commands.resize((size_t)Command::Max); - - commands[(size_t)Command::Mesh] = {"mesh", "<file>", "Visualize the mesh."}; - commands[(size_t)Command::Solution] = {"solution", "<mesh> <solution>", "Visualize the solution."}; - commands[(size_t)Command::ParSolution] = {"psolution", "<np> <mesh prefix> <keep attributes> <solution prefix>", "Visualize the distributed solution."}; - commands[(size_t)Command::Quadrature] = {"quadrature", "<mesh> <quadrature>", "Visualize the quadrature."}; - commands[(size_t)Command::ParQuadrature] = {"pquadrature", "<np> <mesh prefix> <keep attributes> <quadrature prefix>", "Visualize the distributed quadrature."}; - commands[(size_t)Command::DataCollMesh] = {"data_coll_mesh", "<type> <data coll>", "Visualize the mesh from data collection."}; - commands[(size_t)Command::DataCollField] = {"data_coll_field", "<type> <data coll> <field>", "Visualize the field from data collection."}; - commands[(size_t)Command::DataCollQuad] = {"data_coll_quad", "<type> <data coll> <quad>", "Visualize the Q-field from data collection."}; - commands[(size_t)Command::DataCollCycle] = {"data_coll_cycle", "<cycle>", "Preset the cycle of the data collection."}; - commands[(size_t)Command::DataCollProto] = {"data_coll_protocol", "<protocol>", "Preset the protocol of the data collection."}; - commands[(size_t)Command::Screenshot] = {"screenshot", "<file>", "Take a screenshot, saving it to the file."}; - commands[(size_t)Command::Viewcenter] = {"viewcenter", "<x> <y>", "Change the viewcenter."}; - commands[(size_t)Command::Perspective] = {"perspective", "<on/off>", "Turn on or off perspective projection."}; - commands[(size_t)Command::Light] = {"light", "<on/off>", "Turn on or off light."}; - commands[(size_t)Command::View] = {"view", "<theta> <phi>", "Change the solid angle of view."}; - commands[(size_t)Command::Zoom] = {"zoom", "<zoom>", "Change the zoom factor."}; - commands[(size_t)Command::Shading] = {"shading", "<flat/smooth/cool>", "Change the shading algorithm."}; - commands[(size_t)Command::Subdivisions] = {"subdivisions", "<times> <dummy>", "Change the refinement level."}; - commands[(size_t)Command::Valuerange] = {"valuerange", "<min> <max>", "Change the value range."}; - commands[(size_t)Command::Autoscale] = {"autoscale", "<off/on/value/mesh>", "Change the autoscale algorithm."}; - commands[(size_t)Command::Levellines] = {"levellines", "<min> <max> <num>", "Set the level lines."}; - commands[(size_t)Command::AxisNumberFormat] = {"axis_numberformat", "'<format>'", "Set the axis number format."}; - commands[(size_t)Command::ColorbarNumberFormat] = {"colorbar_numberformat", "'<format>'", "Set the colorbar number format."}; - commands[(size_t)Command::Window] = {"window", "<x> <y> <w> <h>", "Set the position and size of the window."}; - commands[(size_t)Command::Keys] = {"keys", "<keys>", "Send the control key sequence."}; - commands[(size_t)Command::Palette] = {"palette", "<index>", "Set the palette index."}; - commands[(size_t)Command::PaletteRepeat] = {"palette_repeat", "<times>", "Set the repetition of the palette."}; - commands[(size_t)Command::ToggleAttributes] = {"toggle_attributes", "<1/0> [[<1/0>] ...];", "Toggle visibility of the attributes."}; - commands[(size_t)Command::Rotmat] = {"rotmat", "<[0,0]> <[1,0]> ... <[3,3]>", "Set the rotation matrix."}; - commands[(size_t)Command::Camera] = {"camera", "<cam[0]> ... <cam[2]> <dir[0]> ... <dir[2]> <up[0]> ... <up[2]>", "Set the camera position, direction and upward vector."}; - commands[(size_t)Command::Scale] = {"scale", "<scale>", "Set the scaling factor."}; - commands[(size_t)Command::Translate] = {"translate", "<x> <y> <z>", "Set the translation coordinates."}; - commands[(size_t)Command::PlotCaption] = {"plot_caption", "'<caption>'", "Set the plot caption."}; -} - void ScriptController::PrintCommands() { cout << "Available commands are:" << endl; - for (const CmdItem &ci : commands) + for (const auto &ci : commands) { cout << "\t" << ci.keyword << " " << ci.params << " - " << ci.desc << endl; } @@ -838,15 +846,6 @@ void ScriptController::ScriptControl() } } -ScriptController::ScriptController(Window &win_) - : win(win_) -{ - if (commands.empty()) - { - InitCommands(); - } -} - void ScriptController::PlayScript(istream &scr) { string word; diff --git a/lib/script_controller.hpp b/lib/script_controller.hpp index 44304ab1..d24f506d 100644 --- a/lib/script_controller.hpp +++ b/lib/script_controller.hpp @@ -45,12 +45,11 @@ class ScriptController static void ScriptIdleFunc(); static void ScriptControl(); - static void InitCommands(); static void PrintCommands(); void ExecuteScriptCommand(); public: - ScriptController(Window &win_); + ScriptController(Window &win_) : win(win_) { } void PlayScript(std::istream &scr); }; diff --git a/lib/stream_reader.cpp b/lib/stream_reader.cpp index 2b528c21..f49c5e06 100644 --- a/lib/stream_reader.cpp +++ b/lib/stream_reader.cpp @@ -11,7 +11,7 @@ #include "stream_reader.hpp" -#include <vector> +#include <array> #include <algorithm> using namespace std; @@ -41,31 +41,30 @@ enum class Command Max }; -struct CmdItem +class StreamCommands { - const char *keyword; - bool keys; - const char *params; - const char *desc; + struct CmdItem + { + const char *keyword; + bool keys; + const char *params; + const char *desc; - bool operator==(const string &key) const { return key == keyword; } -}; + bool operator==(const string &key) const { return key == keyword; } + }; + array<CmdItem,(size_t)Command::Max> commands; -static vector<CmdItem> commands; +public: + StreamCommands(); -StreamReader::StreamReader(DataState &data_) - : data(data_) -{ - if (commands.empty()) - { - InitCommands(); - } -} + array<CmdItem,(size_t)Command::Max>::const_iterator begin() const { return commands.begin(); } + array<CmdItem,(size_t)Command::Max>::const_iterator end() const { return commands.end(); } + const CmdItem& operator[](Command cmd) const { return commands[(size_t)cmd]; } +}; +static const StreamCommands commands; -void StreamReader::InitCommands() +StreamCommands::StreamCommands() { - commands.resize((size_t)Command::Max); - commands[(size_t)Command::Mesh] = {"mesh", false, "<mesh>", "Visualize the mesh."}; commands[(size_t)Command::Solution] = {"solution", false, "<mesh> <solution>", "Visualize the solution."}; commands[(size_t)Command::Quadrature] = {"quadrature", false, "<mesh> <quadrature>", "Visualize the quadrature."}; @@ -90,7 +89,7 @@ void StreamReader::PrintCommands() { cout << "Available commands are:" << endl; - for (const CmdItem &ci : commands) + for (const auto &ci : commands) { cout << "\t" << ci.keyword << " " << ci.params << " - " << ci.desc << endl; } @@ -98,11 +97,6 @@ void StreamReader::PrintCommands() bool StreamReader::SupportsDataType(const string &data_type) { - if (commands.empty()) - { - InitCommands(); - } - auto it = find(commands.begin(), commands.end(), data_type); return it != commands.end(); } @@ -289,7 +283,7 @@ int StreamReader::ReadStream( break; } - if (commands[(size_t)cmd].keys) + if (commands[cmd].keys) { is >> data.keys; } diff --git a/lib/stream_reader.hpp b/lib/stream_reader.hpp index 2fdecaab..5801d362 100644 --- a/lib/stream_reader.hpp +++ b/lib/stream_reader.hpp @@ -25,11 +25,9 @@ class StreamReader { DataState &data; - static void InitCommands(); - public: - StreamReader(DataState &data_); + StreamReader(DataState &data_): data(data_) { } /// Prints available commands static void PrintCommands(); diff --git a/lib/threads.cpp b/lib/threads.cpp index f8abec59..94976d2c 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -11,7 +11,8 @@ #include "visual.hpp" #include "palettes.hpp" -#include <vector> + +#include <array> #include <algorithm> using namespace std; @@ -826,48 +827,29 @@ enum class Command Max }; -struct CmdItem +class ThreadCommands { - const char *keyword; - const char *params; - const char *desc; - - bool operator==(const string &key) const { return key == keyword; } -}; - -static vector<CmdItem> commands; - -communication_thread::communication_thread(StreamCollection _is, - GLVisCommand* cmd) - : is(std::move(_is)), glvis_command(cmd) -{ - new_m = NULL; - new_g = NULL; - - if (commands.empty()) + struct CmdItem { - init_commands(); - } + const char *keyword; + const char *params; + const char *desc; - if (is.size() > 0) - { - tid = std::thread(&communication_thread::execute, this); - } -} + bool operator==(const string &key) const { return key == keyword; } + }; + array<CmdItem,(size_t)Command::Max> commands; -communication_thread::~communication_thread() -{ - if (is.size() > 0) - { - terminate_thread = true; - tid.join(); - } -} +public: + ThreadCommands(); -void communication_thread::init_commands() -{ - commands.resize((size_t)Command::Max); + array<CmdItem,(size_t)Command::Max>::const_iterator begin() const { return commands.begin(); } + array<CmdItem,(size_t)Command::Max>::const_iterator end() const { return commands.end(); } + const CmdItem& operator[](Command cmd) const { return commands[(size_t)cmd]; } +}; +static const ThreadCommands commands; +ThreadCommands::ThreadCommands() +{ commands[(size_t)Command::Parallel] = {"parallel", "<num proc> <proc>", "Prefix for distributed mesh/solution/quadrature."}; commands[(size_t)Command::Screenshot] = {"screenshot", "<file>", "Take a screenshot, saving it to the file."}; commands[(size_t)Command::Viewcenter] = {"viewcenter", "<x> <y>", "Change the viewcenter."}; @@ -893,11 +875,33 @@ void communication_thread::init_commands() commands[(size_t)Command::Autopause] = {"autopause", "<0/off/1/on>", "Turns off or on autopause."}; } +communication_thread::communication_thread(StreamCollection _is, + GLVisCommand* cmd) + : is(std::move(_is)), glvis_command(cmd) +{ + new_m = NULL; + new_g = NULL; + + if (is.size() > 0) + { + tid = std::thread(&communication_thread::execute, this); + } +} + +communication_thread::~communication_thread() +{ + if (is.size() > 0) + { + terminate_thread = true; + tid.join(); + } +} + void communication_thread::print_commands() { StreamReader::PrintCommands(); - for (const CmdItem &ci : commands) + for (const auto &ci : commands) { cout << "\t" << ci.keyword << " " << ci.params << " - " << ci.desc << endl; } diff --git a/lib/threads.hpp b/lib/threads.hpp index 6d31d11b..c63e3e82 100644 --- a/lib/threads.hpp +++ b/lib/threads.hpp @@ -163,7 +163,6 @@ class communication_thread // signal for thread cancellation std::atomic<bool> terminate_thread {false}; - static void init_commands(); static void print_commands(); void execute(); From 6c568f3253c9976021e90f9355f5a50cc95a0f46 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 6 May 2025 07:26:50 -0700 Subject: [PATCH 26/65] Cosmetic change of command lists. --- lib/script_controller.cpp | 4 ++-- lib/stream_reader.cpp | 4 ++-- lib/threads.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index 2a238fd5..9245701f 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -75,8 +75,8 @@ class ScriptCommands public: ScriptCommands(); - array<CmdItem,(size_t)Command::Max>::const_iterator begin() const { return commands.begin(); } - array<CmdItem,(size_t)Command::Max>::const_iterator end() const { return commands.end(); } + decltype(commands)::const_iterator begin() const { return commands.begin(); } + decltype(commands)::const_iterator end() const { return commands.end(); } const CmdItem& operator[](Command cmd) const { return commands[(size_t)cmd]; } }; static const ScriptCommands commands; diff --git a/lib/stream_reader.cpp b/lib/stream_reader.cpp index f49c5e06..5b65cea5 100644 --- a/lib/stream_reader.cpp +++ b/lib/stream_reader.cpp @@ -57,8 +57,8 @@ class StreamCommands public: StreamCommands(); - array<CmdItem,(size_t)Command::Max>::const_iterator begin() const { return commands.begin(); } - array<CmdItem,(size_t)Command::Max>::const_iterator end() const { return commands.end(); } + decltype(commands)::const_iterator begin() const { return commands.begin(); } + decltype(commands)::const_iterator end() const { return commands.end(); } const CmdItem& operator[](Command cmd) const { return commands[(size_t)cmd]; } }; static const StreamCommands commands; diff --git a/lib/threads.cpp b/lib/threads.cpp index 94976d2c..52064a31 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -842,8 +842,8 @@ class ThreadCommands public: ThreadCommands(); - array<CmdItem,(size_t)Command::Max>::const_iterator begin() const { return commands.begin(); } - array<CmdItem,(size_t)Command::Max>::const_iterator end() const { return commands.end(); } + decltype(commands)::const_iterator begin() const { return commands.begin(); } + decltype(commands)::const_iterator end() const { return commands.end(); } const CmdItem& operator[](Command cmd) const { return commands[(size_t)cmd]; } }; static const ThreadCommands commands; From b880ffcdac6f3b8f89dff9bfb8fbd1f82038b270 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 7 May 2025 09:45:52 -0700 Subject: [PATCH 27/65] Minor debugging log change. --- lib/stream_reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stream_reader.cpp b/lib/stream_reader.cpp index 5b65cea5..b8547263 100644 --- a/lib/stream_reader.cpp +++ b/lib/stream_reader.cpp @@ -307,7 +307,7 @@ int StreamReader::ReadStreams(const StreamCollection &input_streams) for (int p = 0; p < nproc; p++) { #ifdef GLVIS_DEBUG - cout << "connection[" << p << "]: reading initial data ... " << flush; + cout << "connection[" << p << "]: reading data ... " << flush; #endif istream &isock = *input_streams[p]; // assuming the "parallel nproc p" part of the stream has been read From ced295ed9d06592e6346e80ebc6c72fc155b56ce Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 7 May 2025 10:45:15 -0700 Subject: [PATCH 28/65] Changed init_nodes to unique_ptr. --- lib/script_controller.cpp | 4 +--- lib/script_controller.hpp | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index 9245701f..a9e30cfc 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -261,7 +261,7 @@ int ScriptController::ScriptReadDisplMesh(istream &scr, DataState &state) Mesh* const m = meshstate.mesh.get(); if (init_nodes == NULL) { - init_nodes = new Vector; + init_nodes.reset(new Vector); meshstate.mesh->GetNodes(*init_nodes); state.SetMesh(NULL); state.SetGridFunction(NULL); @@ -976,8 +976,6 @@ void ScriptController::PlayScript(istream &scr) SDLMainLoop(); worker_thread.join(); - delete init_nodes; init_nodes = NULL; - cout << "Script: min_val = " << scr_min_val << ", max_val = " << scr_max_val << endl; diff --git a/lib/script_controller.hpp b/lib/script_controller.hpp index d24f506d..2f227e82 100644 --- a/lib/script_controller.hpp +++ b/lib/script_controller.hpp @@ -13,6 +13,7 @@ #define GLVIS_SCRIPT_CONTROLLER_HPP #include <iostream> +#include <memory> #include "window.hpp" @@ -29,7 +30,7 @@ class ScriptController istream *script = NULL; int scr_running = 0; int scr_level = 0; - mfem::Vector *init_nodes = NULL; + std::unique_ptr<mfem::Vector> init_nodes; double scr_min_val, scr_max_val; static int ScriptReadSolution(istream &scr, DataState &state); From 8687102153147a231f25c8127e0d041b96446109 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 7 May 2025 10:52:49 -0700 Subject: [PATCH 29/65] Fixed thread-locality of the script controller. --- glvis.cpp | 3 +-- lib/script_controller.cpp | 54 +++++++++++++++++++-------------------- lib/script_controller.hpp | 6 ++--- 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/glvis.cpp b/glvis.cpp index 675ae403..7ef13259 100644 --- a/glvis.cpp +++ b/glvis.cpp @@ -619,8 +619,7 @@ int main (int argc, char *argv[]) } cout << "Running script from file: " << script_file << endl; cout << "You may need to press <space> to execute the script steps." << endl; - ScriptController script(win); - script.PlayScript(scr); + ScriptController::PlayScript(std::move(win), scr); return 0; } diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index a9e30cfc..081590d1 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -846,13 +846,15 @@ void ScriptController::ScriptControl() } } -void ScriptController::PlayScript(istream &scr) +void ScriptController::PlayScript(Window win, istream &scr) { string word; bool done = false; - scr_min_val = numeric_limits<double>::infinity(); - scr_max_val = -scr_min_val; + ScriptController script(std::move(win)); + + script.scr_min_val = numeric_limits<double>::infinity(); + script.scr_max_val = -script.scr_min_val; // read initializing commands while (!done) @@ -882,65 +884,66 @@ void ScriptController::PlayScript(istream &scr) switch (cmd) { case Command::Window: - scr >> win.window_x >> win.window_y >> win.window_w >> win.window_h; + scr >> script.win.window_x >> script.win.window_y >> script.win.window_w >> + script.win.window_h; break; case Command::DataCollCycle: - scr >> dc_cycle; + scr >> script.dc_cycle; break; case Command::DataCollProto: - scr >> dc_protocol; + scr >> script.dc_protocol; break; case Command::Solution: - if (ScriptReadSolution(scr, win.data_state)) + if (ScriptReadSolution(scr, script.win.data_state)) { return; } done = true; // start the visualization break; case Command::Quadrature: - if (ScriptReadQuadrature(scr, win.data_state)) + if (ScriptReadQuadrature(scr, script.win.data_state)) { return; } done = true; // start the visualization break; case Command::ParSolution: - if (ScriptReadParSolution(scr, win.data_state)) + if (ScriptReadParSolution(scr, script.win.data_state)) { return; } done = true; // start the visualization break; case Command::ParQuadrature: - if (ScriptReadParQuadrature(scr, win.data_state)) + if (ScriptReadParQuadrature(scr, script.win.data_state)) { return; } done = true; // start the visualization break; case Command::Mesh: - if (ScriptReadDisplMesh(scr, win.data_state)) + if (script.ScriptReadDisplMesh(scr, script.win.data_state)) { return; } - done = win.data_state.mesh != nullptr; + done = script.win.data_state.mesh != nullptr; break; case Command::DataCollMesh: - if (ScriptReadDataColl(scr, win.data_state)) + if (script.ScriptReadDataColl(scr, script.win.data_state)) { return; } done = true; // start the visualization break; case Command::DataCollField: - if (ScriptReadDataColl(scr, win.data_state, false)) + if (script.ScriptReadDataColl(scr, script.win.data_state, false)) { return; } done = true; // start the visualization break; case Command::DataCollQuad: - if (ScriptReadDataColl(scr, win.data_state, false, true)) + if (script.ScriptReadDataColl(scr, script.win.data_state, false, true)) { return; } @@ -951,10 +954,9 @@ void ScriptController::PlayScript(istream &scr) } } - scr_level = scr_running = 0; - script = &scr; - script_ctrl = this; - win.data_state.keys.clear(); + script.scr_level = script.scr_running = 0; + script.script = &scr; + script.win.data_state.keys.clear(); // Make sure the singleton object returned by GetMainThread() is // initialized from the main thread. @@ -962,22 +964,18 @@ void ScriptController::PlayScript(istream &scr) std::thread worker_thread { - [&](Window local_win) + [&](ScriptController local_script) { - if (local_win.GLVisInitVis({})) + script_ctrl = &local_script; + if (local_script.win.GLVisInitVis({})) { GetAppWindow()->setOnKeyDown(SDLK_SPACE, ScriptControl); - local_win.GLVisStartVis(); + local_script.win.GLVisStartVis(); } }, - std::move(win) + std::move(script) }; SDLMainLoop(); worker_thread.join(); - - cout << "Script: min_val = " << scr_min_val - << ", max_val = " << scr_max_val << endl; - - script = NULL; } diff --git a/lib/script_controller.hpp b/lib/script_controller.hpp index 2f227e82..99b173a5 100644 --- a/lib/script_controller.hpp +++ b/lib/script_controller.hpp @@ -22,7 +22,7 @@ extern const char *string_default; class ScriptController { - Window &win; + Window win; string dc_protocol = string_default; int dc_cycle = 0; @@ -50,9 +50,9 @@ class ScriptController void ExecuteScriptCommand(); public: - ScriptController(Window &win_) : win(win_) { } + ScriptController(Window win_) : win(std::move(win_)) { } - void PlayScript(std::istream &scr); + static void PlayScript(Window win, std::istream &scr); }; #endif // GLVIS_SCRIPT_CONTROLLER_HPP From eebcea9e18b52553454970993c7802dfc25efaac Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Thu, 8 May 2025 13:21:21 -0700 Subject: [PATCH 30/65] Cosmetic change of commands initialization. --- lib/script_controller.cpp | 67 ++++++++++++++++++++------------------- lib/stream_reader.cpp | 37 ++++++++++----------- lib/threads.cpp | 47 +++++++++++++-------------- 3 files changed, 77 insertions(+), 74 deletions(-) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index 081590d1..d89a228d 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -77,45 +77,46 @@ class ScriptCommands decltype(commands)::const_iterator begin() const { return commands.begin(); } decltype(commands)::const_iterator end() const { return commands.end(); } + CmdItem& operator[](Command cmd) { return commands[(size_t)cmd]; } const CmdItem& operator[](Command cmd) const { return commands[(size_t)cmd]; } }; static const ScriptCommands commands; ScriptCommands::ScriptCommands() { - commands[(size_t)Command::Mesh] = {"mesh", "<file>", "Visualize the mesh."}; - commands[(size_t)Command::Solution] = {"solution", "<mesh> <solution>", "Visualize the solution."}; - commands[(size_t)Command::ParSolution] = {"psolution", "<np> <mesh prefix> <keep attributes> <solution prefix>", "Visualize the distributed solution."}; - commands[(size_t)Command::Quadrature] = {"quadrature", "<mesh> <quadrature>", "Visualize the quadrature."}; - commands[(size_t)Command::ParQuadrature] = {"pquadrature", "<np> <mesh prefix> <keep attributes> <quadrature prefix>", "Visualize the distributed quadrature."}; - commands[(size_t)Command::DataCollMesh] = {"data_coll_mesh", "<type> <data coll>", "Visualize the mesh from data collection."}; - commands[(size_t)Command::DataCollField] = {"data_coll_field", "<type> <data coll> <field>", "Visualize the field from data collection."}; - commands[(size_t)Command::DataCollQuad] = {"data_coll_quad", "<type> <data coll> <quad>", "Visualize the Q-field from data collection."}; - commands[(size_t)Command::DataCollCycle] = {"data_coll_cycle", "<cycle>", "Preset the cycle of the data collection."}; - commands[(size_t)Command::DataCollProto] = {"data_coll_protocol", "<protocol>", "Preset the protocol of the data collection."}; - commands[(size_t)Command::Screenshot] = {"screenshot", "<file>", "Take a screenshot, saving it to the file."}; - commands[(size_t)Command::Viewcenter] = {"viewcenter", "<x> <y>", "Change the viewcenter."}; - commands[(size_t)Command::Perspective] = {"perspective", "<on/off>", "Turn on or off perspective projection."}; - commands[(size_t)Command::Light] = {"light", "<on/off>", "Turn on or off light."}; - commands[(size_t)Command::View] = {"view", "<theta> <phi>", "Change the solid angle of view."}; - commands[(size_t)Command::Zoom] = {"zoom", "<zoom>", "Change the zoom factor."}; - commands[(size_t)Command::Shading] = {"shading", "<flat/smooth/cool>", "Change the shading algorithm."}; - commands[(size_t)Command::Subdivisions] = {"subdivisions", "<times> <dummy>", "Change the refinement level."}; - commands[(size_t)Command::Valuerange] = {"valuerange", "<min> <max>", "Change the value range."}; - commands[(size_t)Command::Autoscale] = {"autoscale", "<off/on/value/mesh>", "Change the autoscale algorithm."}; - commands[(size_t)Command::Levellines] = {"levellines", "<min> <max> <num>", "Set the level lines."}; - commands[(size_t)Command::AxisNumberFormat] = {"axis_numberformat", "'<format>'", "Set the axis number format."}; - commands[(size_t)Command::ColorbarNumberFormat] = {"colorbar_numberformat", "'<format>'", "Set the colorbar number format."}; - commands[(size_t)Command::Window] = {"window", "<x> <y> <w> <h>", "Set the position and size of the window."}; - commands[(size_t)Command::Keys] = {"keys", "<keys>", "Send the control key sequence."}; - commands[(size_t)Command::Palette] = {"palette", "<index>", "Set the palette index."}; - commands[(size_t)Command::PaletteRepeat] = {"palette_repeat", "<times>", "Set the repetition of the palette."}; - commands[(size_t)Command::ToggleAttributes] = {"toggle_attributes", "<1/0> [[<1/0>] ...];", "Toggle visibility of the attributes."}; - commands[(size_t)Command::Rotmat] = {"rotmat", "<[0,0]> <[1,0]> ... <[3,3]>", "Set the rotation matrix."}; - commands[(size_t)Command::Camera] = {"camera", "<cam[0]> ... <cam[2]> <dir[0]> ... <dir[2]> <up[0]> ... <up[2]>", "Set the camera position, direction and upward vector."}; - commands[(size_t)Command::Scale] = {"scale", "<scale>", "Set the scaling factor."}; - commands[(size_t)Command::Translate] = {"translate", "<x> <y> <z>", "Set the translation coordinates."}; - commands[(size_t)Command::PlotCaption] = {"plot_caption", "'<caption>'", "Set the plot caption."}; + (*this)[Command::Mesh] = {"mesh", "<file>", "Visualize the mesh."}; + (*this)[Command::Solution] = {"solution", "<mesh> <solution>", "Visualize the solution."}; + (*this)[Command::ParSolution] = {"psolution", "<np> <mesh prefix> <keep attributes> <solution prefix>", "Visualize the distributed solution."}; + (*this)[Command::Quadrature] = {"quadrature", "<mesh> <quadrature>", "Visualize the quadrature."}; + (*this)[Command::ParQuadrature] = {"pquadrature", "<np> <mesh prefix> <keep attributes> <quadrature prefix>", "Visualize the distributed quadrature."}; + (*this)[Command::DataCollMesh] = {"data_coll_mesh", "<type> <data coll>", "Visualize the mesh from data collection."}; + (*this)[Command::DataCollField] = {"data_coll_field", "<type> <data coll> <field>", "Visualize the field from data collection."}; + (*this)[Command::DataCollQuad] = {"data_coll_quad", "<type> <data coll> <quad>", "Visualize the Q-field from data collection."}; + (*this)[Command::DataCollCycle] = {"data_coll_cycle", "<cycle>", "Preset the cycle of the data collection."}; + (*this)[Command::DataCollProto] = {"data_coll_protocol", "<protocol>", "Preset the protocol of the data collection."}; + (*this)[Command::Screenshot] = {"screenshot", "<file>", "Take a screenshot, saving it to the file."}; + (*this)[Command::Viewcenter] = {"viewcenter", "<x> <y>", "Change the viewcenter."}; + (*this)[Command::Perspective] = {"perspective", "<on/off>", "Turn on or off perspective projection."}; + (*this)[Command::Light] = {"light", "<on/off>", "Turn on or off light."}; + (*this)[Command::View] = {"view", "<theta> <phi>", "Change the solid angle of view."}; + (*this)[Command::Zoom] = {"zoom", "<zoom>", "Change the zoom factor."}; + (*this)[Command::Shading] = {"shading", "<flat/smooth/cool>", "Change the shading algorithm."}; + (*this)[Command::Subdivisions] = {"subdivisions", "<times> <dummy>", "Change the refinement level."}; + (*this)[Command::Valuerange] = {"valuerange", "<min> <max>", "Change the value range."}; + (*this)[Command::Autoscale] = {"autoscale", "<off/on/value/mesh>", "Change the autoscale algorithm."}; + (*this)[Command::Levellines] = {"levellines", "<min> <max> <num>", "Set the level lines."}; + (*this)[Command::AxisNumberFormat] = {"axis_numberformat", "'<format>'", "Set the axis number format."}; + (*this)[Command::ColorbarNumberFormat] = {"colorbar_numberformat", "'<format>'", "Set the colorbar number format."}; + (*this)[Command::Window] = {"window", "<x> <y> <w> <h>", "Set the position and size of the window."}; + (*this)[Command::Keys] = {"keys", "<keys>", "Send the control key sequence."}; + (*this)[Command::Palette] = {"palette", "<index>", "Set the palette index."}; + (*this)[Command::PaletteRepeat] = {"palette_repeat", "<times>", "Set the repetition of the palette."}; + (*this)[Command::ToggleAttributes] = {"toggle_attributes", "<1/0> [[<1/0>] ...];", "Toggle visibility of the attributes."}; + (*this)[Command::Rotmat] = {"rotmat", "<[0,0]> <[1,0]> ... <[3,3]>", "Set the rotation matrix."}; + (*this)[Command::Camera] = {"camera", "<cam[0]> ... <cam[2]> <dir[0]> ... <dir[2]> <up[0]> ... <up[2]>", "Set the camera position, direction and upward vector."}; + (*this)[Command::Scale] = {"scale", "<scale>", "Set the scaling factor."}; + (*this)[Command::Translate] = {"translate", "<x> <y> <z>", "Set the translation coordinates."}; + (*this)[Command::PlotCaption] = {"plot_caption", "'<caption>'", "Set the plot caption."}; } int ScriptController::ScriptReadSolution(istream &scr, DataState &state) diff --git a/lib/stream_reader.cpp b/lib/stream_reader.cpp index b8547263..24b40d85 100644 --- a/lib/stream_reader.cpp +++ b/lib/stream_reader.cpp @@ -59,30 +59,31 @@ class StreamCommands decltype(commands)::const_iterator begin() const { return commands.begin(); } decltype(commands)::const_iterator end() const { return commands.end(); } + CmdItem& operator[](Command cmd) { return commands[(size_t)cmd]; } const CmdItem& operator[](Command cmd) const { return commands[(size_t)cmd]; } }; static const StreamCommands commands; StreamCommands::StreamCommands() { - commands[(size_t)Command::Mesh] = {"mesh", false, "<mesh>", "Visualize the mesh."}; - commands[(size_t)Command::Solution] = {"solution", false, "<mesh> <solution>", "Visualize the solution."}; - commands[(size_t)Command::Quadrature] = {"quadrature", false, "<mesh> <quadrature>", "Visualize the quadrature."}; - commands[(size_t)Command::Fem2D] = {"fem2d_data", false, "<mesh> <data>", "Visualize the 2D scalar data."}; - commands[(size_t)Command::VFem2D] = {"vfem2d_data", false, "<mesh> <data_x> <data_y>", "Visualize the 2D vector data."}; - commands[(size_t)Command::VFem2D_keys] = {"vfem2d_data_keys", true, "<mesh> <data_x> <data_y> <keys>", "Visualize the 2D vector data and apply control keys."}; - commands[(size_t)Command::Fem3D] = {"fem3d_data", false, "<mesh> <data>", "Visualize the 3D scalar data."}; - commands[(size_t)Command::VFem3D] = {"vfem3d_data", false, "<mesh> <data_x> <data_y> <data_z>", "Visualize the 3D vector data."}; - commands[(size_t)Command::VFem3D_keys] = {"vfem3d_data_keys", true, "<mesh> <data_x> <data_y> <data_z> <keys>", "Visualize the 3D vector data and apply control keys."}; - commands[(size_t)Command::Fem2D_GF] = {"fem2d_gf_data", false, "<mesh> <solution>", "Visualize the 2D scalar grid function."}; - commands[(size_t)Command::Fem2D_GF_keys] = {"fem2d_gf_data_keys", true, "<mesh> <solution> <keys>", "Visualize the 2D scalar grid function and apply control keys."}; - commands[(size_t)Command::VFem2D_GF] = {"vfem2d_gf_data", false, "<mesh> <solution>", "Visualize the 2D vector grid function."}; - commands[(size_t)Command::VFem2D_GF_keys] = {"vfem2d_gf_data_keys", true, "<mesh> <solution> <keys>", "Visualize the 2D vector grid function and apply control keys."}; - commands[(size_t)Command::Fem3D_GF] = {"fem3d_gf_data", false, "<mesh> <solution>", "Visualize the 3D scalar grid function."}; - commands[(size_t)Command::Fem3D_GF_keys] = {"fem3d_gf_data_keys", true, "<mesh> <solution> <keys>", "Visualize the 3D scalar grid function and apply control keys."}; - commands[(size_t)Command::VFem3D_GF] = {"vfem3d_gf_data", false, "<mesh> <solution>", "Visualize the 3D vector grid function."}; - commands[(size_t)Command::VFem3D_GF_keys] = {"vfem3d_gf_data_keys", true, "<mesh> <solution> <keys>", "Visualize the 3D vector grid function and apply control keys."}; - commands[(size_t)Command::RawScalar2D] = {"raw_scalar_2d", false, "<data>", "Visualize the 2D scalar data (see stream_reader.cpp)."}; + (*this)[Command::Mesh] = {"mesh", false, "<mesh>", "Visualize the mesh."}; + (*this)[Command::Solution] = {"solution", false, "<mesh> <solution>", "Visualize the solution."}; + (*this)[Command::Quadrature] = {"quadrature", false, "<mesh> <quadrature>", "Visualize the quadrature."}; + (*this)[Command::Fem2D] = {"fem2d_data", false, "<mesh> <data>", "Visualize the 2D scalar data."}; + (*this)[Command::VFem2D] = {"vfem2d_data", false, "<mesh> <data_x> <data_y>", "Visualize the 2D vector data."}; + (*this)[Command::VFem2D_keys] = {"vfem2d_data_keys", true, "<mesh> <data_x> <data_y> <keys>", "Visualize the 2D vector data and apply control keys."}; + (*this)[Command::Fem3D] = {"fem3d_data", false, "<mesh> <data>", "Visualize the 3D scalar data."}; + (*this)[Command::VFem3D] = {"vfem3d_data", false, "<mesh> <data_x> <data_y> <data_z>", "Visualize the 3D vector data."}; + (*this)[Command::VFem3D_keys] = {"vfem3d_data_keys", true, "<mesh> <data_x> <data_y> <data_z> <keys>", "Visualize the 3D vector data and apply control keys."}; + (*this)[Command::Fem2D_GF] = {"fem2d_gf_data", false, "<mesh> <solution>", "Visualize the 2D scalar grid function."}; + (*this)[Command::Fem2D_GF_keys] = {"fem2d_gf_data_keys", true, "<mesh> <solution> <keys>", "Visualize the 2D scalar grid function and apply control keys."}; + (*this)[Command::VFem2D_GF] = {"vfem2d_gf_data", false, "<mesh> <solution>", "Visualize the 2D vector grid function."}; + (*this)[Command::VFem2D_GF_keys] = {"vfem2d_gf_data_keys", true, "<mesh> <solution> <keys>", "Visualize the 2D vector grid function and apply control keys."}; + (*this)[Command::Fem3D_GF] = {"fem3d_gf_data", false, "<mesh> <solution>", "Visualize the 3D scalar grid function."}; + (*this)[Command::Fem3D_GF_keys] = {"fem3d_gf_data_keys", true, "<mesh> <solution> <keys>", "Visualize the 3D scalar grid function and apply control keys."}; + (*this)[Command::VFem3D_GF] = {"vfem3d_gf_data", false, "<mesh> <solution>", "Visualize the 3D vector grid function."}; + (*this)[Command::VFem3D_GF_keys] = {"vfem3d_gf_data_keys", true, "<mesh> <solution> <keys>", "Visualize the 3D vector grid function and apply control keys."}; + (*this)[Command::RawScalar2D] = {"raw_scalar_2d", false, "<data>", "Visualize the 2D scalar data (see stream_reader.cpp)."}; } void StreamReader::PrintCommands() diff --git a/lib/threads.cpp b/lib/threads.cpp index 52064a31..0d55180e 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -844,35 +844,36 @@ class ThreadCommands decltype(commands)::const_iterator begin() const { return commands.begin(); } decltype(commands)::const_iterator end() const { return commands.end(); } + CmdItem& operator[](Command cmd) { return commands[(size_t)cmd]; } const CmdItem& operator[](Command cmd) const { return commands[(size_t)cmd]; } }; static const ThreadCommands commands; ThreadCommands::ThreadCommands() { - commands[(size_t)Command::Parallel] = {"parallel", "<num proc> <proc>", "Prefix for distributed mesh/solution/quadrature."}; - commands[(size_t)Command::Screenshot] = {"screenshot", "<file>", "Take a screenshot, saving it to the file."}; - commands[(size_t)Command::Viewcenter] = {"viewcenter", "<x> <y>", "Change the viewcenter."}; - commands[(size_t)Command::View] = {"view", "<theta> <phi>", "Change the solid angle of view."}; - commands[(size_t)Command::Zoom] = {"zoom", "<zoom>", "Change the zoom factor."}; - commands[(size_t)Command::Shading] = {"shading", "<flat/smooth/cool>", "Change the shading algorithm."}; - commands[(size_t)Command::Subdivisions] = {"subdivisions", "<times> <dummy>", "Change the refinement level."}; - commands[(size_t)Command::Valuerange] = {"valuerange", "<min> <max>", "Change the value range."}; - commands[(size_t)Command::Autoscale] = {"autoscale", "<off/on/value/mesh>", "Change the autoscale algorithm."}; - commands[(size_t)Command::Levellines] = {"levellines", "<min> <max> <num>", "Set the level lines."}; - commands[(size_t)Command::AxisNumberFormat] = {"axis_numberformat", "'<format>'", "Set the axis number format."}; - commands[(size_t)Command::ColorbarNumberFormat] = {"colorbar_numberformat", "'<format>'", "Set the colorbar number format."}; - commands[(size_t)Command::WindowSize] = {"window_size", "<w> <h>", "Set the size of the window."}; - commands[(size_t)Command::WindowGeometry] = {"window_geometry", "<x> <y> <w> <h>", "Set the position and size of the window."}; - commands[(size_t)Command::WindowTitle] = {"window_title", "'<title>'", "Set title of the window."}; - commands[(size_t)Command::Keys] = {"keys", "<keys>", "Send the control key sequence."}; - commands[(size_t)Command::Palette] = {"palette", "<index>", "Set the palette index."}; - commands[(size_t)Command::PaletteRepeat] = {"palette_repeat", "<times>", "Set the repetition of the palette."}; - commands[(size_t)Command::Camera] = {"camera", "<cam[0]> ... <cam[2]> <dir[0]> ... <dir[2]> <up[0]> ... <up[2]>", "Set the camera position, direction and upward vector."}; - commands[(size_t)Command::PlotCaption] = {"plot_caption", "'<caption>'", "Set the plot caption."}; - commands[(size_t)Command::AxisLabels] = {"axis_labels", "'<x label>' '<y label>' '<z label>'", "Set labels of the axes."}; - commands[(size_t)Command::Pause] = {"pause", "", "Stop the stream until space is pressed."}; - commands[(size_t)Command::Autopause] = {"autopause", "<0/off/1/on>", "Turns off or on autopause."}; + (*this)[Command::Parallel] = {"parallel", "<num proc> <proc>", "Prefix for distributed mesh/solution/quadrature."}; + (*this)[Command::Screenshot] = {"screenshot", "<file>", "Take a screenshot, saving it to the file."}; + (*this)[Command::Viewcenter] = {"viewcenter", "<x> <y>", "Change the viewcenter."}; + (*this)[Command::View] = {"view", "<theta> <phi>", "Change the solid angle of view."}; + (*this)[Command::Zoom] = {"zoom", "<zoom>", "Change the zoom factor."}; + (*this)[Command::Shading] = {"shading", "<flat/smooth/cool>", "Change the shading algorithm."}; + (*this)[Command::Subdivisions] = {"subdivisions", "<times> <dummy>", "Change the refinement level."}; + (*this)[Command::Valuerange] = {"valuerange", "<min> <max>", "Change the value range."}; + (*this)[Command::Autoscale] = {"autoscale", "<off/on/value/mesh>", "Change the autoscale algorithm."}; + (*this)[Command::Levellines] = {"levellines", "<min> <max> <num>", "Set the level lines."}; + (*this)[Command::AxisNumberFormat] = {"axis_numberformat", "'<format>'", "Set the axis number format."}; + (*this)[Command::ColorbarNumberFormat] = {"colorbar_numberformat", "'<format>'", "Set the colorbar number format."}; + (*this)[Command::WindowSize] = {"window_size", "<w> <h>", "Set the size of the window."}; + (*this)[Command::WindowGeometry] = {"window_geometry", "<x> <y> <w> <h>", "Set the position and size of the window."}; + (*this)[Command::WindowTitle] = {"window_title", "'<title>'", "Set title of the window."}; + (*this)[Command::Keys] = {"keys", "<keys>", "Send the control key sequence."}; + (*this)[Command::Palette] = {"palette", "<index>", "Set the palette index."}; + (*this)[Command::PaletteRepeat] = {"palette_repeat", "<times>", "Set the repetition of the palette."}; + (*this)[Command::Camera] = {"camera", "<cam[0]> ... <cam[2]> <dir[0]> ... <dir[2]> <up[0]> ... <up[2]>", "Set the camera position, direction and upward vector."}; + (*this)[Command::PlotCaption] = {"plot_caption", "'<caption>'", "Set the plot caption."}; + (*this)[Command::AxisLabels] = {"axis_labels", "'<x label>' '<y label>' '<z label>'", "Set labels of the axes."}; + (*this)[Command::Pause] = {"pause", "", "Stop the stream until space is pressed."}; + (*this)[Command::Autopause] = {"autopause", "<0/off/1/on>", "Turns off or on autopause."}; } communication_thread::communication_thread(StreamCollection _is, From 78d568fe6c7b8592c4120cd426b0e65ba8864903 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Thu, 8 May 2025 13:43:00 -0700 Subject: [PATCH 31/65] Minor script debugging print out. --- lib/script_controller.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index d89a228d..27cf8785 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -951,6 +951,7 @@ void ScriptController::PlayScript(Window win, istream &scr) done = true; // start the visualization break; default: + cout << "Command not supported at this level: " << word << endl; break; } } From 69499093624e5eeed59fe78f750195f9751374d2 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Mon, 12 May 2025 09:50:46 -0700 Subject: [PATCH 32/65] Fixed the order of deletion for cleaner cleanup. --- lib/aux_vis.cpp | 5 +++++ lib/aux_vis.hpp | 3 +++ lib/window.cpp | 1 + 3 files changed, 9 insertions(+) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 015f55ca..dbd48b0c 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -369,6 +369,11 @@ void RunVisualization() wnd->mainLoop(); #endif InitIdleFuncs(); +} + +void EndVisualization() +{ + visualize = 0; delete wnd; wnd = nullptr; } diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index 4f412247..4c03b48d 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -35,6 +35,9 @@ void SetVisualizationScene(VisualizationScene * scene, /// Start the infinite visualization loop. void RunVisualization(); +/// End the visualization and destroy the window. +void EndVisualization(); + /// Send expose event. In our case MyReshape is executed and Draw after it. void SendExposeEvent(); diff --git a/lib/window.cpp b/lib/window.cpp index 1966069d..c5573ddc 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -174,6 +174,7 @@ void Window::GLVisStartVis() { RunVisualization(); internal.vs.reset(); + EndVisualization(); if (glvis_command) { glvis_command->Terminate(); From bcd8fcb32d47e75ada71d725977daf3085e5f9bf Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 13 May 2025 22:07:07 -0700 Subject: [PATCH 33/65] Moved ownership of SdlWindow to Window and removed GetAppWindow() uses. --- lib/aux_js.cpp | 12 ++++++------ lib/aux_vis.cpp | 11 +++-------- lib/aux_vis.hpp | 5 +---- lib/openglvis.cpp | 4 ++-- lib/script_controller.cpp | 2 +- lib/threads.cpp | 4 ++-- lib/vsdata.cpp | 8 ++++---- lib/window.cpp | 10 ++++++---- lib/window.hpp | 3 +++ 9 files changed, 28 insertions(+), 31 deletions(-) diff --git a/lib/aux_js.cpp b/lib/aux_js.cpp index e3a14f56..49a34fac 100644 --- a/lib/aux_js.cpp +++ b/lib/aux_js.cpp @@ -44,7 +44,7 @@ using namespace mfem; void display(std::stringstream & commands, const int w, const int h) { // reset antialiasing - GetAppWindow()->getRenderer().setAntialiasing(0); + win.wnd->getRenderer().setAntialiasing(0); std::string word; double minv = 0.0, maxv = 0.0; @@ -207,13 +207,13 @@ int updateParallelStreams(const StringArray & streams) // void iterVisualization() { - GetAppWindow()->mainIter(); + win.wnd->mainIter(); } void setCanvasId(const std::string & id) { std::cout << "glvis: setting canvas id to " << id << std::endl; - GetAppWindow()->setCanvasId(id); + win.wnd->setCanvasId(id); } void disableKeyHandling() @@ -244,7 +244,7 @@ void processKey(int sym, bool ctrl=false, bool shift=false, bool alt=false) mod |= ctrl ? KMOD_CTRL : 0; mod |= shift ? KMOD_SHIFT : 0; mod |= alt ? KMOD_ALT : 0; - GetAppWindow()->callKeyDown(sym, mod); + win.wnd->callKeyDown(sym, mod); } void setupResizeEventCallback(const std::string & id) @@ -274,7 +274,7 @@ std::string getHelpString() em::val getScreenBuffer(bool flip_y=false) { MyExpose(); - auto * wnd = GetAppWindow(); + auto * wnd = win.wnd; int w, h; wnd->getGLDrawSize(w, h); @@ -317,7 +317,7 @@ em::val getScreenBuffer(bool flip_y=false) em::val getPNGByteArray() { constexpr const char * filename = "im.png"; - auto * wnd = GetAppWindow(); + auto * wnd = win.wnd; int w, h; wnd->getGLDrawSize(w, h); diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index dbd48b0c..716e7a72 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -85,7 +85,7 @@ void SetUseHiDPI(bool status) void MyExpose(GLsizei w, GLsizei h); void MyExpose(); -int InitVisualization (const char name[], int x, int y, int w, int h) +SdlWindow* InitVisualization(const char name[], int x, int y, int w, int h) { #ifdef GLVIS_DEBUG @@ -96,7 +96,7 @@ int InitVisualization (const char name[], int x, int y, int w, int h) wnd = new SdlWindow(); if (!wnd->createWindow(name, x, y, w, h, wndLegacyGl)) { - return 1; + return NULL; } } else @@ -199,7 +199,7 @@ int InitVisualization (const char name[], int x, int y, int w, int h) #endif locscene = nullptr; - return 0; + return wnd; } void SendKeySequence(const char *seq) @@ -369,12 +369,7 @@ void RunVisualization() wnd->mainLoop(); #endif InitIdleFuncs(); -} - -void EndVisualization() -{ visualize = 0; - delete wnd; wnd = nullptr; } diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index 4c03b48d..97286abf 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -27,7 +27,7 @@ class GLVisCommand; void SetGLVisCommand(GLVisCommand *cmd); /// Initializes the visualization and some keys. -int InitVisualization(const char name[], int x, int y, int w, int h); +SdlWindow* InitVisualization(const char name[], int x, int y, int w, int h); void SetVisualizationScene(VisualizationScene * scene, int view = 3, const char *keys = NULL); @@ -35,9 +35,6 @@ void SetVisualizationScene(VisualizationScene * scene, /// Start the infinite visualization loop. void RunVisualization(); -/// End the visualization and destroy the window. -void EndVisualization(); - /// Send expose event. In our case MyReshape is executed and Draw after it. void SendExposeEvent(); diff --git a/lib/openglvis.cpp b/lib/openglvis.cpp index c5981a75..7b54361e 100644 --- a/lib/openglvis.cpp +++ b/lib/openglvis.cpp @@ -1068,12 +1068,12 @@ void VisualizationScene::ToggleBackground() if (background == BG_BLK) { background = BG_WHITE; - GetAppWindow()->getRenderer().setClearColor(1.f, 1.f, 1.f, 1.f); + wnd->getRenderer().setClearColor(1.f, 1.f, 1.f, 1.f); } else { background = BG_BLK; - GetAppWindow()->getRenderer().setClearColor(0.f, 0.f, 0.f, 1.f); + wnd->getRenderer().setClearColor(0.f, 0.f, 0.f, 1.f); } } diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index 27cf8785..25c3d57a 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -971,7 +971,7 @@ void ScriptController::PlayScript(Window win, istream &scr) script_ctrl = &local_script; if (local_script.win.GLVisInitVis({})) { - GetAppWindow()->setOnKeyDown(SDLK_SPACE, ScriptControl); + local_script.win.wnd->setOnKeyDown(SDLK_SPACE, ScriptControl); local_script.win.GLVisStartVis(); } }, diff --git a/lib/threads.cpp b/lib/threads.cpp index 0d55180e..d4a725db 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -24,7 +24,7 @@ GLVisCommand::GLVisCommand(Window &win_) : win(win_) { // should be set in this thread by a call to InitVisualization() - thread_wnd = GetAppWindow(); + thread_wnd = win.wnd.get(); num_waiting = 0; terminating = false; @@ -500,7 +500,7 @@ int GLVisCommand::Execute() cout << "Command: screenshot -> " << screenshot_filename << endl; // Allow SdlWindow to handle the expose and screenshot action, in case // any actions need to be taken before MyExpose(). - GetAppWindow()->screenshot(screenshot_filename, true); + thread_wnd->screenshot(screenshot_filename, true); break; } diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index d80e6fab..e3ee16f9 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -933,8 +933,8 @@ void KeyKPressed() void KeyAPressed() { - bool curr_aa = GetAppWindow()->getRenderer().getAntialiasing(); - GetAppWindow()->getRenderer().setAntialiasing(!curr_aa); + bool curr_aa = window->wnd->getRenderer().getAntialiasing(); + window->wnd->getRenderer().setAntialiasing(!curr_aa); cout << "Multisampling/Antialiasing: " << strings_off_on[!curr_aa ? 1 : 0] << endl; @@ -1371,7 +1371,7 @@ void VisualizationSceneScalarData::Init() { vsdata = this; window = &win; - wnd = GetAppWindow(); + wnd = win.wnd.get(); arrow_type = arrow_scaling_type = 0; scaling = 0; @@ -1753,7 +1753,7 @@ void VisualizationSceneScalarData::SetLevelLines ( void VisualizationSceneScalarData::PrintState() { - cout << "\nkeys: " << GetAppWindow()->getSavedKeys() << "\n" + cout << "\nkeys: " << wnd->getSavedKeys() << "\n" << "\nlight " << strings_off_on[use_light ? 1 : 0] << "\nperspective " << strings_off_on[OrthogonalProjection ? 0 : 1] << "\nviewcenter " << ViewCenterX << ' ' << ViewCenterY diff --git a/lib/window.cpp b/lib/window.cpp index c5573ddc..2b3c5a17 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -48,7 +48,9 @@ bool Window::GLVisInitVis(StreamCollection input_streams) const char *win_title = (window_title == string_default) ? window_titles[(int)field_type] : window_title; - if (InitVisualization(win_title, window_x, window_y, window_w, window_h)) + internal.wnd.reset(InitVisualization(win_title, window_x, window_y, window_w, + window_h)); + if (!wnd) { cerr << "Initializing the visualization failed." << endl; return false; @@ -56,7 +58,7 @@ bool Window::GLVisInitVis(StreamCollection input_streams) if (input_streams.size() > 0) { - GetAppWindow()->setOnKeyDown(SDLK_SPACE, ThreadsPauseFunc); + wnd->setOnKeyDown(SDLK_SPACE, ThreadsPauseFunc); internal.glvis_command.reset(new GLVisCommand(*this)); SetGLVisCommand(glvis_command.get()); internal.comm_thread.reset(new communication_thread(std::move(input_streams), @@ -67,7 +69,7 @@ bool Window::GLVisInitVis(StreamCollection input_streams) if (data_state.quad_f) { - GetAppWindow()->setOnKeyDown('Q', SwitchQuadSolution); + wnd->setOnKeyDown('Q', SwitchQuadSolution); } double mesh_range = -1.0; @@ -174,7 +176,7 @@ void Window::GLVisStartVis() { RunVisualization(); internal.vs.reset(); - EndVisualization(); + internal.wnd.reset(); if (glvis_command) { glvis_command->Terminate(); diff --git a/lib/window.hpp b/lib/window.hpp index b9f794cd..28f8df5c 100644 --- a/lib/window.hpp +++ b/lib/window.hpp @@ -17,6 +17,7 @@ #include "data_state.hpp" #include "stream_reader.hpp" +class SdlWindow; class VisualizationSceneScalarData; class communication_thread; class GLVisCommand; @@ -29,6 +30,7 @@ struct Window private: struct { + std::unique_ptr<SdlWindow> wnd; std::unique_ptr<VisualizationSceneScalarData> vs; std::unique_ptr<communication_thread> comm_thread; std::unique_ptr<GLVisCommand> glvis_command; @@ -36,6 +38,7 @@ struct Window public: DataState data_state; + const std::unique_ptr<SdlWindow> &wnd{internal.wnd}; const std::unique_ptr<VisualizationSceneScalarData> &vs{internal.vs}; const std::unique_ptr<communication_thread> &comm_thread{internal.comm_thread}; const std::unique_ptr<GLVisCommand> &glvis_command{internal.glvis_command}; From 3b91045192e3c8545742fe7859ead2cb69b084a2 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 13 May 2025 22:14:09 -0700 Subject: [PATCH 34/65] Moved assignment of SdlWindow in VisualizationScene from Init to constructor. --- lib/openglvis.cpp | 6 ++++-- lib/openglvis.hpp | 2 +- lib/vsdata.cpp | 3 +-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/openglvis.cpp b/lib/openglvis.cpp index 7b54361e..6d131896 100644 --- a/lib/openglvis.cpp +++ b/lib/openglvis.cpp @@ -112,8 +112,10 @@ void Camera::Print() << std::endl; } -VisualizationScene::VisualizationScene() +VisualizationScene::VisualizationScene(SdlWindow &wnd_) { + wnd = &wnd_; + translmat = glm::mat4(1.0); rotmat = glm::mat4(1.0); rotmat = glm::rotate(rotmat, glm::radians(-60.f), glm::vec3(1.f, 0.f, 0.f)); @@ -130,7 +132,7 @@ VisualizationScene::VisualizationScene() cut_updated = false; background = BG_WHITE; - GetAppWindow()->getRenderer().setClearColor(1.f, 1.f, 1.f, 1.f); + wnd->getRenderer().setClearColor(1.f, 1.f, 1.f, 1.f); _use_cust_l0_pos = false; light_mat_idx = 3; use_light = true; diff --git a/lib/openglvis.hpp b/lib/openglvis.hpp index 1455242d..9cbb3899 100644 --- a/lib/openglvis.hpp +++ b/lib/openglvis.hpp @@ -171,7 +171,7 @@ class VisualizationScene const gl3::GlDrawable &gl_drawable); public: - VisualizationScene(); + VisualizationScene(SdlWindow &wnd); virtual ~VisualizationScene(); int spinning, OrthogonalProjection, print, movie; diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index e3ee16f9..d7dbb5d2 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -1355,7 +1355,7 @@ void VisualizationSceneScalarData::SetAutoscale(int _autoscale) } VisualizationSceneScalarData::VisualizationSceneScalarData( - Window &win_, bool init) : win(win_) + Window &win_, bool init) : VisualizationScene(*win_.wnd), win(win_) { mesh = win.data_state.mesh.get(); mesh_coarse = win.data_state.mesh_quad.get(); @@ -1371,7 +1371,6 @@ void VisualizationSceneScalarData::Init() { vsdata = this; window = &win; - wnd = win.wnd.get(); arrow_type = arrow_scaling_type = 0; scaling = 0; From 21ab52098eee039738fb219662a6f40166c15813 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 13 May 2025 22:26:10 -0700 Subject: [PATCH 35/65] Fix of handling failed window creation. --- lib/aux_vis.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 716e7a72..238562ee 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -96,6 +96,8 @@ SdlWindow* InitVisualization(const char name[], int x, int y, int w, int h) wnd = new SdlWindow(); if (!wnd->createWindow(name, x, y, w, h, wndLegacyGl)) { + delete wnd; + wnd = nullptr; return NULL; } } From 20ec3f8d1322c2850b8457a06fed6ff9e2ab0b48 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 27 May 2025 10:45:40 -0700 Subject: [PATCH 36/65] Fixed canvas id in sdl.cpp. --- lib/sdl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/sdl.cpp b/lib/sdl.cpp index 3131d757..471a431a 100644 --- a/lib/sdl.cpp +++ b/lib/sdl.cpp @@ -549,13 +549,13 @@ void SdlWindow::getWindowSize(int& w, int& h) if (handle.isInitialized()) { #ifdef __EMSCRIPTEN__ - if (canvas_id_.empty()) + if (canvas_id.empty()) { - std::cerr << "error: id is undefined: " << canvas_id_ << std::endl; + std::cerr << "error: id is undefined: " << canvas_id << std::endl; return; } double dw, dh; - auto err = emscripten_get_element_css_size(canvas_id_.c_str(), &dw, &dh); + auto err = emscripten_get_element_css_size(canvas_id.c_str(), &dw, &dh); w = int(dw); h = int(dh); if (err != EMSCRIPTEN_RESULT_SUCCESS) From 2a02262fca431aadd16dc0f5cdbb1e131f142289 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 27 May 2025 10:55:32 -0700 Subject: [PATCH 37/65] Fixed definition of GLWindow in aux_js. --- lib/aux_js.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/aux_js.cpp b/lib/aux_js.cpp index 49a34fac..5016c959 100644 --- a/lib/aux_js.cpp +++ b/lib/aux_js.cpp @@ -13,6 +13,7 @@ #include "palettes.hpp" #include "stream_reader.hpp" #include "visual.hpp" +#include "glwindow.hpp" #ifdef GLVIS_USE_LIBPNG #include <png.h> From cf1bb1e0a21bf6145ab4f7844ba0a51e995d66d9 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 27 May 2025 11:07:02 -0700 Subject: [PATCH 38/65] Fixed dereferencing of window in aux_js. --- lib/aux_js.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/aux_js.cpp b/lib/aux_js.cpp index 5016c959..0f9677ee 100644 --- a/lib/aux_js.cpp +++ b/lib/aux_js.cpp @@ -275,9 +275,8 @@ std::string getHelpString() em::val getScreenBuffer(bool flip_y=false) { MyExpose(); - auto * wnd = win.wnd; int w, h; - wnd->getGLDrawSize(w, h); + win.wnd->getGLDrawSize(w, h); // 4 bytes for rgba const size_t buffer_size = w*h*4; @@ -318,13 +317,12 @@ em::val getScreenBuffer(bool flip_y=false) em::val getPNGByteArray() { constexpr const char * filename = "im.png"; - auto * wnd = win.wnd; int w, h; - wnd->getGLDrawSize(w, h); + win.wnd->getGLDrawSize(w, h); MyExpose(); // save to in-memory file - int status = SaveAsPNG(filename, w, h, wnd->isHighDpi(), true); + int status = SaveAsPNG(filename, w, h, win.wnd->isHighDpi(), true); if (status != 0) { fprintf(stderr, "unable to generate png\n"); From 171ed0fe6c97d140c194e6a144e307b75a465732 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 28 May 2025 12:25:22 -0700 Subject: [PATCH 39/65] Revert "Fixed canvas id in sdl.cpp." This reverts commit 20ec3f8d1322c2850b8457a06fed6ff9e2ab0b48. --- lib/sdl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/sdl.cpp b/lib/sdl.cpp index 471a431a..3131d757 100644 --- a/lib/sdl.cpp +++ b/lib/sdl.cpp @@ -549,13 +549,13 @@ void SdlWindow::getWindowSize(int& w, int& h) if (handle.isInitialized()) { #ifdef __EMSCRIPTEN__ - if (canvas_id.empty()) + if (canvas_id_.empty()) { - std::cerr << "error: id is undefined: " << canvas_id << std::endl; + std::cerr << "error: id is undefined: " << canvas_id_ << std::endl; return; } double dw, dh; - auto err = emscripten_get_element_css_size(canvas_id.c_str(), &dw, &dh); + auto err = emscripten_get_element_css_size(canvas_id_.c_str(), &dw, &dh); w = int(dw); h = int(dh); if (err != EMSCRIPTEN_RESULT_SUCCESS) From 54df563a804157d1770112e525f01ba9346bd2b3 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 28 May 2025 12:37:02 -0700 Subject: [PATCH 40/65] Revert "Fixed definition of GLWindow in aux_js." This reverts commit 2a02262fca431aadd16dc0f5cdbb1e131f142289. --- lib/aux_js.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/aux_js.cpp b/lib/aux_js.cpp index 0f9677ee..401af562 100644 --- a/lib/aux_js.cpp +++ b/lib/aux_js.cpp @@ -13,7 +13,6 @@ #include "palettes.hpp" #include "stream_reader.hpp" #include "visual.hpp" -#include "glwindow.hpp" #ifdef GLVIS_USE_LIBPNG #include <png.h> From b9e80d167c973e05740fc5a362a379235ab5372d Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 28 May 2025 14:02:51 -0700 Subject: [PATCH 41/65] Fixed typo in NOTICE. --- NOTICE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NOTICE b/NOTICE index 799bac34..e548fdff 100644 --- a/NOTICE +++ b/NOTICE @@ -25,6 +25,6 @@ This project distributes the sources of several external software products with their own respective licenses which can be found in their code and attached license files. These software products and their licenses are as follows: -* GL2PS (linalg/gl2ps.{h,c}) -- Custom 1-clause license +* GL2PS (lib/gl2ps.{h,c}) -- Custom 1-clause license * Additional color palettes (share/palettes-crameri.txt) -- MIT license * Additional color palettes (share/palettes-cet.txt) -- CC BY 4.0 license From 6919572123cf4ca4d7d9e46f1a4876c8e7324dd3 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 28 May 2025 14:20:41 -0700 Subject: [PATCH 42/65] Guarded GL2PS for emscripten. --- lib/aux_vis.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 238562ee..9e85bac5 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -20,7 +20,9 @@ #include "sdl.hpp" #include "palettes.hpp" #include "visual.hpp" +#ifndef __EMSCRIPTEN__ #include "gl2ps.h" +#endif #if defined(GLVIS_USE_LIBTIFF) #include "tiffio.h" @@ -1176,6 +1178,7 @@ void KeyS() SendExposeEvent(); } +#ifndef __EMSCRIPTEN__ inline GL2PSvertex CreatePrintVtx(gl3::FeedbackVertex v) { return @@ -1218,6 +1221,7 @@ void PrintCaptureBuffer(gl3::CaptureBuffer& cbuf) gl2psText(entry.text.c_str(), "Times", 12); } } +#endif void KeyCtrlP() { From 818b538770e69fbd0eb02a7360d77f090aa7b58f Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 28 May 2025 14:26:30 -0700 Subject: [PATCH 43/65] Guarded threads for emscripten. --- lib/aux_vis.cpp | 2 ++ lib/visual.hpp | 2 ++ lib/vsdata.cpp | 4 ++-- lib/window.cpp | 2 ++ lib/window.hpp | 4 ++++ 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 9e85bac5..d64e9c67 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -460,6 +460,7 @@ void InitIdleFuncs() } } +#ifndef __EMSCRIPTEN__ bool CommunicationIdleFunc() { int status = glvis_command->Execute(); @@ -475,6 +476,7 @@ bool CommunicationIdleFunc() } return false; } +#endif bool MainIdleFunc() { diff --git a/lib/visual.hpp b/lib/visual.hpp index 8c5e5dfa..9507294b 100644 --- a/lib/visual.hpp +++ b/lib/visual.hpp @@ -22,7 +22,9 @@ #include "vssolution3d.hpp" #include "vsvector.hpp" #include "vsvector3d.hpp" +#ifndef __EMSCRIPTEN__ #include "threads.hpp" +#endif #include "gl/types.hpp" #endif diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index d7dbb5d2..03e1eba1 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -23,9 +23,9 @@ using namespace std; #include "aux_vis.hpp" #include "material.hpp" #include "palettes.hpp" +#ifndef __EMSCRIPTEN__ #include "threads.hpp" - -#include "gl2ps.h" +#endif const char *strings_off_on[] = { "off", "on" }; diff --git a/lib/window.cpp b/lib/window.cpp index 2b3c5a17..f4e72b23 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -56,6 +56,7 @@ bool Window::GLVisInitVis(StreamCollection input_streams) return false; } +#ifndef __EMSCRIPTEN__ if (input_streams.size() > 0) { wnd->setOnKeyDown(SDLK_SPACE, ThreadsPauseFunc); @@ -64,6 +65,7 @@ bool Window::GLVisInitVis(StreamCollection input_streams) internal.comm_thread.reset(new communication_thread(std::move(input_streams), glvis_command.get())); } +#endif locwin = this; diff --git a/lib/window.hpp b/lib/window.hpp index 28f8df5c..f44f6d1e 100644 --- a/lib/window.hpp +++ b/lib/window.hpp @@ -32,16 +32,20 @@ struct Window { std::unique_ptr<SdlWindow> wnd; std::unique_ptr<VisualizationSceneScalarData> vs; +#ifndef __EMSCRIPTEN__ std::unique_ptr<communication_thread> comm_thread; std::unique_ptr<GLVisCommand> glvis_command; +#endif } internal; public: DataState data_state; const std::unique_ptr<SdlWindow> &wnd{internal.wnd}; const std::unique_ptr<VisualizationSceneScalarData> &vs{internal.vs}; +#ifndef __EMSCRIPTEN__ const std::unique_ptr<communication_thread> &comm_thread{internal.comm_thread}; const std::unique_ptr<GLVisCommand> &glvis_command{internal.glvis_command}; +#endif int window_x = 0; // not a command line option int window_y = 0; // not a command line option From a44d2afb2e03b049884dcccac7d1925d4c29c60b Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 28 May 2025 15:10:07 -0700 Subject: [PATCH 44/65] Fixed aux_vis for emscripten. --- lib/aux_vis.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index d64e9c67..fda13994 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -15,6 +15,7 @@ #include <cmath> #include <chrono> #include <regex> +#include <thread> #include "mfem.hpp" #include "sdl.hpp" @@ -1286,7 +1287,9 @@ void ThreadsPauseFunc(GLenum state) { if (state & KMOD_CTRL) { +#ifndef __EMSCRIPTEN__ glvis_command->ToggleAutopause(); +#endif } else { From 130c59bc96f97286cf206bba87410da080d77937 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 28 May 2025 15:22:15 -0700 Subject: [PATCH 45/65] Fixed include in script controller. --- lib/script_controller.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index 25c3d57a..d7097907 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -17,6 +17,7 @@ #include <array> #include <algorithm> +#include <thread> using namespace std; using namespace mfem; From 01fa33ae4edbd61c396dc6c470602db9d9363004 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 28 May 2025 15:31:00 -0700 Subject: [PATCH 46/65] Fixed window for emscripten. --- lib/window.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/window.cpp b/lib/window.cpp index f4e72b23..9f6189bc 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -179,12 +179,14 @@ void Window::GLVisStartVis() RunVisualization(); internal.vs.reset(); internal.wnd.reset(); +#ifndef __EMSCRIPTEN__ if (glvis_command) { glvis_command->Terminate(); internal.comm_thread.reset(); internal.glvis_command.reset(); } +#endif cout << "GLVis window closed." << endl; } From caa662abdc380a6e15186785b1132c288db8d231 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 28 May 2025 16:10:21 -0700 Subject: [PATCH 47/65] Removed script controller from glvis-js compilation. --- makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/makefile b/makefile index 3f53000a..18e33226 100644 --- a/makefile +++ b/makefile @@ -261,7 +261,8 @@ ALL_SOURCE_FILES = \ lib/vsvector.cpp lib/vsvector3d.cpp lib/window.cpp OBJC_SOURCE_FILES = $(if $(NOTMAC),,lib/sdl_mac.mm) DESKTOP_ONLY_SOURCE_FILES = \ - lib/gl/renderer_ff.cpp lib/threads.cpp lib/gl2ps.c lib/sdl_x11.cpp + lib/gl/renderer_ff.cpp lib/threads.cpp lib/gl2ps.c \ + lib/script_controller.cpp lib/sdl_x11.cpp WEB_ONLY_SOURCE_FILES = lib/aux_js.cpp LOGO_FILE = share/logo.rgba LOGO_FILE_CPP = $(LOGO_FILE).bin.cpp From c30e83687e776513aaa33c867fdd2a691748c186 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 28 May 2025 16:48:42 -0700 Subject: [PATCH 48/65] Fixed window title default value. --- glvis.cpp | 7 ++++++- lib/window.cpp | 2 +- lib/window.hpp | 7 ++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/glvis.cpp b/glvis.cpp index 7ef13259..90d39ff0 100644 --- a/glvis.cpp +++ b/glvis.cpp @@ -374,6 +374,7 @@ int main (int argc, char *argv[]) const char *stream_file = string_none; const char *script_file = string_none; const char *palette_file = string_none; + const char *window_title = string_default; const char *font_name = string_default; int portnum = 19916; int multisample = GetMultisample(); @@ -457,7 +458,7 @@ int main (int argc, char *argv[]) "Set the window width."); args.AddOption(&win.window_h, "-wh", "--window-height", "Set the window height."); - args.AddOption(&win.window_title, "-wt", "--window-title", + args.AddOption(&window_title, "-wt", "--window-title", "Set the window title."); args.AddOption(&c_plot_caption, "-c", "--plot-caption", "Set the plot caption (visible when colorbar is visible)."); @@ -552,6 +553,10 @@ int main (int argc, char *argv[]) { win.data_state.keys = arg_keys; } + if (window_title != string_default) + { + win.window_title = window_title; + } if (font_name != string_default) { SetFont(font_name); diff --git a/lib/window.cpp b/lib/window.cpp index 9f6189bc..34056d8d 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -45,7 +45,7 @@ bool Window::GLVisInitVis(StreamCollection input_streams) "GLVis [vector data]", }; - const char *win_title = (window_title == string_default) ? + const char *win_title = (window_title == nullptr) ? window_titles[(int)field_type] : window_title; internal.wnd.reset(InitVisualization(win_title, window_x, window_y, window_w, diff --git a/lib/window.hpp b/lib/window.hpp index f44f6d1e..1c2bc8e1 100644 --- a/lib/window.hpp +++ b/lib/window.hpp @@ -22,9 +22,6 @@ class VisualizationSceneScalarData; class communication_thread; class GLVisCommand; -extern const char *string_none; -extern const char *string_default; - struct Window { private: @@ -43,7 +40,7 @@ struct Window const std::unique_ptr<SdlWindow> &wnd{internal.wnd}; const std::unique_ptr<VisualizationSceneScalarData> &vs{internal.vs}; #ifndef __EMSCRIPTEN__ - const std::unique_ptr<communication_thread> &comm_thread{internal.comm_thread}; + const std::unique_ptr<communication_thread> &comm_thread {internal.comm_thread}; const std::unique_ptr<GLVisCommand> &glvis_command{internal.glvis_command}; #endif @@ -51,7 +48,7 @@ struct Window int window_y = 0; // not a command line option int window_w = 400; int window_h = 350; - const char *window_title = string_default; + const char *window_title = nullptr; std::string plot_caption; std::string extra_caption; From f1db631008169b04494fc40d1c9cb0f27c80cf30 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 3 Jun 2025 00:22:09 -0700 Subject: [PATCH 49/65] Moved init of grid function to the constructor of VizualizationSceneSolution. --- lib/vssolution.cpp | 10 +++++----- lib/vssolution.hpp | 2 -- lib/vsvector.cpp | 3 --- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/lib/vssolution.cpp b/lib/vssolution.cpp index 44638f00..cb995dcc 100644 --- a/lib/vssolution.cpp +++ b/lib/vssolution.cpp @@ -426,19 +426,19 @@ VisualizationSceneSolution::VisualizationSceneSolution( v_normals = &win.data_state.normals; } + if (win.data_state.grid_f) + { + rsol = win.data_state.grid_f.get(); + } + if (init) { Init(); - if (win.data_state.grid_f) - { - SetGridFunction(*win.data_state.grid_f); - } } } void VisualizationSceneSolution::Init() { - rsol = NULL; vssol = this; drawelems = 1; diff --git a/lib/vssolution.hpp b/lib/vssolution.hpp index b41be912..ef77db97 100644 --- a/lib/vssolution.hpp +++ b/lib/vssolution.hpp @@ -92,8 +92,6 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData std::string GetHelpString() const override; - void SetGridFunction(GridFunction & u) { rsol = &u; } - void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol, GridFunction *new_u = NULL); diff --git a/lib/vsvector.cpp b/lib/vsvector.cpp index 206f47fd..80189ef5 100644 --- a/lib/vsvector.cpp +++ b/lib/vsvector.cpp @@ -286,9 +286,6 @@ VisualizationSceneVector::VisualizationSceneVector(Window &win_) if (VecGridF) { - // VisualizationSceneSolution::Init() sets rsol = NULL ! - SetGridFunction(*VecGridF); - mesh->GetNodes(vc0); if (vc0.Size() != VecGridF->Size()) { From 2b461c0391a6b21704d44322ae0200598eab1335 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 3 Jun 2025 01:30:39 -0700 Subject: [PATCH 50/65] Refactored init/update of visualization scenes and used internal solution vector for 2D scalar data. --- lib/data_state.cpp | 11 +---------- lib/vssolution.cpp | 16 ++++++++++++++++ lib/vssolution.hpp | 9 +++++++-- lib/vssolution3d.cpp | 7 +++++++ lib/vssolution3d.hpp | 9 +++++++-- lib/vsvector.cpp | 9 +++++---- lib/vsvector3d.cpp | 3 ++- lib/vsvector3d.hpp | 2 +- lib/window.cpp | 16 +++------------- 9 files changed, 49 insertions(+), 33 deletions(-) diff --git a/lib/data_state.cpp b/lib/data_state.cpp index 461f233b..3bc95e53 100644 --- a/lib/data_state.cpp +++ b/lib/data_state.cpp @@ -311,7 +311,6 @@ void DataState::SetMeshSolution() } cout << "Number of colors: " << grid_f->Max() + 1 << endl; } - grid_f->GetNodalValues(sol); if (save_coloring) { const char col_fname[] = "GLVis_coloring.gf"; @@ -358,15 +357,7 @@ void DataState::SetGridFunctionSolution(int gf_component) return; } - if (grid_f->VectorDim() == 1) - { - grid_f->GetNodalValues(sol); - type = FieldType::SCALAR; - } - else - { - type = FieldType::VECTOR; - } + type = (grid_f->VectorDim() == 1) ? FieldType::SCALAR : FieldType::VECTOR; } void DataState::SetQuadFunctionSolution(int qf_component) diff --git a/lib/vssolution.cpp b/lib/vssolution.cpp index cb995dcc..6f6338c5 100644 --- a/lib/vssolution.cpp +++ b/lib/vssolution.cpp @@ -429,10 +429,15 @@ VisualizationSceneSolution::VisualizationSceneSolution( if (win.data_state.grid_f) { rsol = win.data_state.grid_f.get(); + sol = new Vector(mesh->GetNV()); } if (init) { + if (rsol) + { + rsol->GetNodalValues(*sol); + } Init(); } } @@ -524,6 +529,10 @@ void VisualizationSceneSolution::Init() VisualizationSceneSolution::~VisualizationSceneSolution() { + if (rsol) + { + delete sol; + } } void VisualizationSceneSolution::ToggleDrawElems() @@ -587,6 +596,13 @@ void VisualizationSceneSolution::ToggleDrawElems() } } +void VisualizationSceneSolution::NewMeshAndSolution( + GridFunction *new_u, Mesh *new_mc) +{ + new_u->GetNodalValues(*sol); + NewMeshAndSolution(new_u->FESpace()->GetMesh(), new_mc, sol, new_u); +} + void VisualizationSceneSolution::NewMeshAndSolution( Mesh *new_m, Mesh *new_mc, Vector *new_sol, GridFunction *new_u) { diff --git a/lib/vssolution.hpp b/lib/vssolution.hpp index ef77db97..2b9418ef 100644 --- a/lib/vssolution.hpp +++ b/lib/vssolution.hpp @@ -58,6 +58,9 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData void Init(); + void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol, + GridFunction *new_u); + void FindNewBox(double rx[], double ry[], double rval[]); void DrawCPLine(gl3::GlBuilder& bld, @@ -92,8 +95,10 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData std::string GetHelpString() const override; - void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol, - GridFunction *new_u = NULL); + void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol) + { NewMeshAndSolution(new_m, new_mc, sol, NULL); } + + void NewMeshAndSolution(GridFunction *new_u, Mesh *new_mc); void SetNewScalingFromBox() override; void FindNewBox(bool prepare) override; diff --git a/lib/vssolution3d.cpp b/lib/vssolution3d.cpp index ada41aec..0a360188 100644 --- a/lib/vssolution3d.cpp +++ b/lib/vssolution3d.cpp @@ -821,6 +821,13 @@ VisualizationSceneSolution3d::~VisualizationSceneSolution3d() delete [] node_pos; } +void VisualizationSceneSolution3d::NewMeshAndSolution( + GridFunction *new_u, Mesh *new_mc) +{ + new_u->GetNodalValues(*sol); + NewMeshAndSolution(new_u->FESpace()->GetMesh(), new_mc, sol, new_u); +} + void VisualizationSceneSolution3d::NewMeshAndSolution( Mesh *new_m, Mesh *new_mc, Vector *new_sol, GridFunction *new_u) { diff --git a/lib/vssolution3d.hpp b/lib/vssolution3d.hpp index 30ad530e..be02dac1 100644 --- a/lib/vssolution3d.hpp +++ b/lib/vssolution3d.hpp @@ -47,6 +47,9 @@ class VisualizationSceneSolution3d : public VisualizationSceneScalarData void Init(); + void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol, + GridFunction *new_u); + void GetFaceNormals(const int FaceNo, const int side, const IntegrationRule &ir, DenseMatrix &normals); @@ -123,8 +126,10 @@ class VisualizationSceneSolution3d : public VisualizationSceneScalarData void SetGridFunction (GridFunction *gf) { GridF = gf; } - void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol, - GridFunction *new_u = NULL); + void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol) + { NewMeshAndSolution(new_m, new_mc, new_sol, NULL); } + + void NewMeshAndSolution(GridFunction *new_u, Mesh *new_mc); virtual ~VisualizationSceneSolution3d(); diff --git a/lib/vsvector.cpp b/lib/vsvector.cpp index 80189ef5..fd93347a 100644 --- a/lib/vsvector.cpp +++ b/lib/vsvector.cpp @@ -276,12 +276,11 @@ VisualizationSceneVector::VisualizationSceneVector(Window &win_) } else { + sol = new Vector(mesh -> GetNV()); solx = &win.data_state.solu; soly = &win.data_state.solv; } - sol = new Vector(mesh -> GetNV()); - Init(); if (VecGridF) @@ -512,13 +511,15 @@ void VisualizationSceneVector::Init() VisualizationSceneVector::~VisualizationSceneVector() { - delete sol; - if (VecGridF) { delete soly; delete solx; } + else + { + delete sol; + } } void VisualizationSceneVector::GetRefinedValues( diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index c9f99f90..edf82c5f 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -464,7 +464,7 @@ VisualizationSceneVector3d::~VisualizationSceneVector3d() } void VisualizationSceneVector3d::NewMeshAndSolution( - Mesh *new_m, Mesh *new_mc, GridFunction *new_v) + GridFunction *new_v, Mesh *new_mc) { delete sol; if (VecGridF) @@ -475,6 +475,7 @@ void VisualizationSceneVector3d::NewMeshAndSolution( delete GridF; delete sfes; } + Mesh *new_m = new_v->FESpace()->GetMesh(); if (mesh->GetNV() != new_m->GetNV()) { delete [] node_pos; diff --git a/lib/vsvector3d.hpp b/lib/vsvector3d.hpp index e15a89b9..34d93596 100644 --- a/lib/vsvector3d.hpp +++ b/lib/vsvector3d.hpp @@ -41,7 +41,7 @@ class VisualizationSceneVector3d : public VisualizationSceneSolution3d VisualizationSceneVector3d(Window &win); - void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, GridFunction *new_v); + void NewMeshAndSolution(GridFunction *new_v, Mesh *new_mc); virtual ~VisualizationSceneVector3d(); diff --git a/lib/window.cpp b/lib/window.cpp index 3b4ec21d..4dc3d3b9 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -78,10 +78,6 @@ bool Window::GLVisInitVis(StreamCollection input_streams) if (field_type == DataState::FieldType::SCALAR || field_type == DataState::FieldType::MESH) { - if (data_state.grid_f) - { - data_state.grid_f->GetNodalValues(data_state.sol); - } if (data_state.mesh->SpaceDimension() == 2) { internal.vs.reset(new VisualizationSceneSolution(*this)); @@ -221,10 +217,7 @@ void Window::ResetMeshAndSolution(DataState &ss) { VisualizationSceneSolution *vss = dynamic_cast<VisualizationSceneSolution *>(internal.vs.get()); - // use the local vector as pointer is invalid after the move - ss.grid_f->GetNodalValues(data_state.sol); - vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &data_state.sol, - ss.grid_f.get()); + vss->NewMeshAndSolution(ss.grid_f.get(), ss.mesh_quad.get()); } else { @@ -239,10 +232,7 @@ void Window::ResetMeshAndSolution(DataState &ss) { VisualizationSceneSolution3d *vss = dynamic_cast<VisualizationSceneSolution3d *>(internal.vs.get()); - // use the local vector as pointer is invalid after the move - ss.grid_f->GetNodalValues(data_state.sol); - vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &data_state.sol, - ss.grid_f.get()); + vss->NewMeshAndSolution(ss.grid_f.get(), ss.mesh_quad.get()); } else { @@ -250,7 +240,7 @@ void Window::ResetMeshAndSolution(DataState &ss) VisualizationSceneVector3d *vss = dynamic_cast<VisualizationSceneVector3d *>(internal.vs.get()); - vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), ss.grid_f.get()); + vss->NewMeshAndSolution(ss.grid_f.get(), ss.mesh_quad.get()); } } } From 14a76f7507e8516e9c7c2c1ec008265b423ccfb4 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 3 Jun 2025 01:53:53 -0700 Subject: [PATCH 51/65] Used internal vector also for 3D scalar data. --- lib/vssolution3d.cpp | 16 +++++++++++++--- lib/vssolution3d.hpp | 2 -- lib/vsvector3d.cpp | 9 +++++---- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/vssolution3d.cpp b/lib/vssolution3d.cpp index 0a360188..42ae0d6a 100644 --- a/lib/vssolution3d.cpp +++ b/lib/vssolution3d.cpp @@ -691,13 +691,19 @@ VisualizationSceneSolution3d::VisualizationSceneSolution3d(Window &win_, bool init) : VisualizationSceneScalarData(win_, false) { + if (win.data_state.grid_f) + { + GridF = win.data_state.grid_f.get(); + sol = new Vector(mesh->GetNV()); + } + if (init) { - Init(); - if (win.data_state.grid_f) + if (GridF) { - SetGridFunction(win.data_state.grid_f.get()); + GridF->GetNodalValues(*sol); } + Init(); } } @@ -818,6 +824,10 @@ void VisualizationSceneSolution3d::Init() VisualizationSceneSolution3d::~VisualizationSceneSolution3d() { + if (GridF) + { + delete sol; + } delete [] node_pos; } diff --git a/lib/vssolution3d.hpp b/lib/vssolution3d.hpp index be02dac1..94fd4aef 100644 --- a/lib/vssolution3d.hpp +++ b/lib/vssolution3d.hpp @@ -124,8 +124,6 @@ class VisualizationSceneSolution3d : public VisualizationSceneScalarData VisualizationSceneSolution3d(Window &win, bool init = true); - void SetGridFunction (GridFunction *gf) { GridF = gf; } - void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol) { NewMeshAndSolution(new_m, new_mc, new_sol, NULL); } diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index edf82c5f..22012b12 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -368,13 +368,12 @@ VisualizationSceneVector3d::VisualizationSceneVector3d(Window &win_) } else { + sol = new Vector(mesh->GetNV()); solx = &win.data_state.solu; soly = &win.data_state.solv; solz = &win.data_state.solw; } - sol = new Vector(mesh->GetNV()); - Init(); } @@ -451,8 +450,6 @@ int VisualizationSceneVector3d::GetFunctionAutoRefineFactor() VisualizationSceneVector3d::~VisualizationSceneVector3d() { - delete sol; - if (VecGridF) { delete solz; @@ -461,6 +458,10 @@ VisualizationSceneVector3d::~VisualizationSceneVector3d() delete GridF; delete sfes; } + else + { + delete sol; + } } void VisualizationSceneVector3d::NewMeshAndSolution( From b02c28619bac55dc14413b1ec4eff42cb259427a Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 3 Jun 2025 02:02:25 -0700 Subject: [PATCH 52/65] Minor unification of the interface. --- lib/vssolution.cpp | 6 +++--- lib/vssolution.hpp | 2 +- lib/vssolution3d.cpp | 6 +++--- lib/vssolution3d.hpp | 2 +- lib/vsvector3d.cpp | 8 ++++---- lib/vsvector3d.hpp | 2 +- lib/window.cpp | 6 +++--- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/vssolution.cpp b/lib/vssolution.cpp index 6f6338c5..09a1db79 100644 --- a/lib/vssolution.cpp +++ b/lib/vssolution.cpp @@ -597,10 +597,10 @@ void VisualizationSceneSolution::ToggleDrawElems() } void VisualizationSceneSolution::NewMeshAndSolution( - GridFunction *new_u, Mesh *new_mc) + GridFunction &new_u, Mesh *new_mc) { - new_u->GetNodalValues(*sol); - NewMeshAndSolution(new_u->FESpace()->GetMesh(), new_mc, sol, new_u); + new_u.GetNodalValues(*sol); + NewMeshAndSolution(new_u.FESpace()->GetMesh(), new_mc, sol, &new_u); } void VisualizationSceneSolution::NewMeshAndSolution( diff --git a/lib/vssolution.hpp b/lib/vssolution.hpp index 2b9418ef..0e6da9dc 100644 --- a/lib/vssolution.hpp +++ b/lib/vssolution.hpp @@ -98,7 +98,7 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol) { NewMeshAndSolution(new_m, new_mc, sol, NULL); } - void NewMeshAndSolution(GridFunction *new_u, Mesh *new_mc); + void NewMeshAndSolution(GridFunction &new_u, Mesh *new_mc = NULL); void SetNewScalingFromBox() override; void FindNewBox(bool prepare) override; diff --git a/lib/vssolution3d.cpp b/lib/vssolution3d.cpp index 42ae0d6a..05d67123 100644 --- a/lib/vssolution3d.cpp +++ b/lib/vssolution3d.cpp @@ -832,10 +832,10 @@ VisualizationSceneSolution3d::~VisualizationSceneSolution3d() } void VisualizationSceneSolution3d::NewMeshAndSolution( - GridFunction *new_u, Mesh *new_mc) + GridFunction &new_u, Mesh *new_mc) { - new_u->GetNodalValues(*sol); - NewMeshAndSolution(new_u->FESpace()->GetMesh(), new_mc, sol, new_u); + new_u.GetNodalValues(*sol); + NewMeshAndSolution(new_u.FESpace()->GetMesh(), new_mc, sol, &new_u); } void VisualizationSceneSolution3d::NewMeshAndSolution( diff --git a/lib/vssolution3d.hpp b/lib/vssolution3d.hpp index 94fd4aef..b74c665e 100644 --- a/lib/vssolution3d.hpp +++ b/lib/vssolution3d.hpp @@ -127,7 +127,7 @@ class VisualizationSceneSolution3d : public VisualizationSceneScalarData void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol) { NewMeshAndSolution(new_m, new_mc, new_sol, NULL); } - void NewMeshAndSolution(GridFunction *new_u, Mesh *new_mc); + void NewMeshAndSolution(GridFunction &new_u, Mesh *new_mc = NULL); virtual ~VisualizationSceneSolution3d(); diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index 22012b12..1d0ab341 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -465,7 +465,7 @@ VisualizationSceneVector3d::~VisualizationSceneVector3d() } void VisualizationSceneVector3d::NewMeshAndSolution( - GridFunction *new_v, Mesh *new_mc) + GridFunction &new_v, Mesh *new_mc) { delete sol; if (VecGridF) @@ -476,7 +476,7 @@ void VisualizationSceneVector3d::NewMeshAndSolution( delete GridF; delete sfes; } - Mesh *new_m = new_v->FESpace()->GetMesh(); + Mesh *new_m = new_v.FESpace()->GetMesh(); if (mesh->GetNV() != new_m->GetNV()) { delete [] node_pos; @@ -484,7 +484,7 @@ void VisualizationSceneVector3d::NewMeshAndSolution( } Mesh *old_m = mesh; - VecGridF = new_v; + VecGridF = &new_v; mesh = new_m; mesh_coarse = new_mc; @@ -501,7 +501,7 @@ void VisualizationSceneVector3d::NewMeshAndSolution( } } - FiniteElementSpace *new_fes = new_v->FESpace(); + FiniteElementSpace *new_fes = new_v.FESpace(); FindNodePos(); diff --git a/lib/vsvector3d.hpp b/lib/vsvector3d.hpp index 34d93596..11bb6423 100644 --- a/lib/vsvector3d.hpp +++ b/lib/vsvector3d.hpp @@ -41,7 +41,7 @@ class VisualizationSceneVector3d : public VisualizationSceneSolution3d VisualizationSceneVector3d(Window &win); - void NewMeshAndSolution(GridFunction *new_v, Mesh *new_mc); + void NewMeshAndSolution(GridFunction &new_v, Mesh *new_mc = NULL); virtual ~VisualizationSceneVector3d(); diff --git a/lib/window.cpp b/lib/window.cpp index 4dc3d3b9..96c4fd3b 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -217,7 +217,7 @@ void Window::ResetMeshAndSolution(DataState &ss) { VisualizationSceneSolution *vss = dynamic_cast<VisualizationSceneSolution *>(internal.vs.get()); - vss->NewMeshAndSolution(ss.grid_f.get(), ss.mesh_quad.get()); + vss->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); } else { @@ -232,7 +232,7 @@ void Window::ResetMeshAndSolution(DataState &ss) { VisualizationSceneSolution3d *vss = dynamic_cast<VisualizationSceneSolution3d *>(internal.vs.get()); - vss->NewMeshAndSolution(ss.grid_f.get(), ss.mesh_quad.get()); + vss->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); } else { @@ -240,7 +240,7 @@ void Window::ResetMeshAndSolution(DataState &ss) VisualizationSceneVector3d *vss = dynamic_cast<VisualizationSceneVector3d *>(internal.vs.get()); - vss->NewMeshAndSolution(ss.grid_f.get(), ss.mesh_quad.get()); + vss->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); } } } From ae9e3fba425a733b83563ea83c9bf0197932ad04 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 3 Jun 2025 20:36:18 -0700 Subject: [PATCH 53/65] Fixed init of grid function in visualization scene. --- lib/vssolution.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vssolution.hpp b/lib/vssolution.hpp index 0e6da9dc..bea82f7b 100644 --- a/lib/vssolution.hpp +++ b/lib/vssolution.hpp @@ -27,7 +27,7 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData { protected: Vector *v_normals{}; - GridFunction *rsol; + GridFunction *rsol{}; int drawmesh, drawelems, drawnums, draworder; int drawbdr, draw_cp; From fcefd7cd6484efc386bc318f8d6045279c8a4a4f Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 3 Jun 2025 21:09:35 -0700 Subject: [PATCH 54/65] Improved compatibility test for update of solution. --- lib/window.cpp | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/lib/window.cpp b/lib/window.cpp index 96c4fd3b..b058128a 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -195,7 +195,10 @@ void Window::SwitchQuadSolution(DataState::QuadSolution quad_type) bool Window::SetNewMeshAndSolution(DataState new_state) { if (new_state.mesh->SpaceDimension() == data_state.mesh->SpaceDimension() && - new_state.grid_f->VectorDim() == data_state.grid_f->VectorDim()) + new_state.GetType() == data_state.GetType() && + (((new_state.grid_f && data_state.grid_f) && + (new_state.grid_f->VectorDim() == data_state.grid_f->VectorDim())) + ||(!new_state.grid_f && !data_state.grid_f))) { ResetMeshAndSolution(new_state); @@ -213,26 +216,47 @@ void Window::ResetMeshAndSolution(DataState &ss) { if (ss.mesh->SpaceDimension() == 2) { - if (ss.grid_f->VectorDim() == 1) + if (ss.GetType() != DataState::FieldType::VECTOR) { VisualizationSceneSolution *vss = dynamic_cast<VisualizationSceneSolution *>(internal.vs.get()); - vss->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); + if (ss.grid_f) + { + vss->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); + } + else + { + std::cerr << "Not implemented" << std::endl; + } } else { VisualizationSceneVector *vsv = dynamic_cast<VisualizationSceneVector *>(internal.vs.get()); - vsv->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); + if (ss.grid_f) + { + vsv->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); + } + else + { + std::cerr << "Not implemented" << std::endl; + } } } else { - if (ss.grid_f->VectorDim() == 1) + if (ss.GetType() != DataState::FieldType::VECTOR) { VisualizationSceneSolution3d *vss = dynamic_cast<VisualizationSceneSolution3d *>(internal.vs.get()); - vss->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); + if (ss.grid_f) + { + vss->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); + } + else + { + std::cerr << "Not implemented" << std::endl; + } } else { @@ -240,7 +264,14 @@ void Window::ResetMeshAndSolution(DataState &ss) VisualizationSceneVector3d *vss = dynamic_cast<VisualizationSceneVector3d *>(internal.vs.get()); - vss->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); + if (ss.grid_f) + { + vss->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); + } + else + { + std::cerr << "Not implemented" << std::endl; + } } } } From 756d620743d6364043c3bdf022bd948d8fe87ce2 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 3 Jun 2025 21:57:14 -0700 Subject: [PATCH 55/65] Improved stream handling for scalar data. --- lib/threads.cpp | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/threads.cpp b/lib/threads.cpp index d4a725db..449ca33c 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -453,27 +453,30 @@ int GLVisCommand::Execute() case NEW_MESH_AND_SOLUTION: { double mesh_range = -1.0; - if (!new_state.grid_f) + switch (new_state.GetType()) { - if (!new_state.quad_f) - { - new_state.save_coloring = false; - new_state.SetMeshSolution(); + case DataState::FieldType::MESH: mesh_range = new_state.grid_f->Max() + 1.0; - } - else - { - auto qs = win.data_state.GetQuadSolution(); - if (qs != DataState::QuadSolution::NONE) + break; + case DataState::FieldType::SCALAR: + case DataState::FieldType::VECTOR: + if (new_state.quad_f) { - new_state.SetQuadSolution(qs); + auto qs = win.data_state.GetQuadSolution(); + if (qs != DataState::QuadSolution::NONE) + { + new_state.SetQuadSolution(qs); + } + else + { + new_state.SetQuadSolution(); + } + new_state.ExtrudeMeshAndSolution(); } - else - { - new_state.SetQuadSolution(); - } - new_state.ExtrudeMeshAndSolution(); - } + break; + default: + cerr << "Unknown field type" << endl; + break; } if (win.SetNewMeshAndSolution(std::move(new_state))) { From e8b17601f802c152afb85ba4aadfdf643d211c02 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 3 Jun 2025 23:00:02 -0700 Subject: [PATCH 56/65] Added update of raw data. --- lib/vssolution.hpp | 2 +- lib/vsvector.cpp | 42 ++++++++++++++++++++++++++++-------------- lib/vsvector.hpp | 7 +++++++ lib/vsvector3d.cpp | 40 ++++++++++++++++++++++++++++------------ lib/vsvector3d.hpp | 7 +++++++ lib/window.cpp | 25 +++++++++++++++++++++---- 6 files changed, 92 insertions(+), 31 deletions(-) diff --git a/lib/vssolution.hpp b/lib/vssolution.hpp index bea82f7b..7583fa08 100644 --- a/lib/vssolution.hpp +++ b/lib/vssolution.hpp @@ -96,7 +96,7 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData std::string GetHelpString() const override; void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol) - { NewMeshAndSolution(new_m, new_mc, sol, NULL); } + { NewMeshAndSolution(new_m, new_mc, new_sol, NULL); } void NewMeshAndSolution(GridFunction &new_u, Mesh *new_mc = NULL); diff --git a/lib/vsvector.cpp b/lib/vsvector.cpp index fd93347a..67fc4157 100644 --- a/lib/vsvector.cpp +++ b/lib/vsvector.cpp @@ -397,6 +397,13 @@ void VisualizationSceneVector::CycleVec2Scalar(int print) } void VisualizationSceneVector::NewMeshAndSolution(GridFunction &vgf, Mesh *mc) +{ + NewMeshAndSolution(vgf.FESpace()->GetMesh(), mc, solx, soly, &vgf); +} + +void VisualizationSceneVector::NewMeshAndSolution( + Mesh *new_m, Mesh *new_mc, Vector *new_sol_x, Vector *new_sol_y, + GridFunction *vgf) { delete sol; @@ -407,10 +414,9 @@ void VisualizationSceneVector::NewMeshAndSolution(GridFunction &vgf, Mesh *mc) } Mesh *old_m = mesh; - Mesh *new_mesh = vgf.FESpace()->GetMesh(); - mesh = new_mesh; - mesh_coarse = mc; - VecGridF = &vgf; + mesh = new_m; + mesh_coarse = new_mc; + VecGridF = vgf; // If the number of elements changes, recompute the refinement factor if (mesh->GetNE() != old_m->GetNE()) @@ -429,20 +435,28 @@ void VisualizationSceneVector::NewMeshAndSolution(GridFunction &vgf, Mesh *mc) } } - solx = new Vector(mesh->GetNV()); - soly = new Vector(mesh->GetNV()); + if (vgf) + { + solx = new Vector(mesh->GetNV()); + soly = new Vector(mesh->GetNV()); - vgf.GetNodalValues(*solx, 1); - vgf.GetNodalValues(*soly, 2); + vgf->GetNodalValues(*solx, 1); + vgf->GetNodalValues(*soly, 2); - mesh->GetNodes(vc0); - if (vc0.Size() != vgf.Size()) - { - vc0.Destroy(); + mesh->GetNodes(vc0); + if (vc0.Size() != vgf->Size()) + { + vc0.Destroy(); + } + else + { + vc0 += *vgf; + } } else { - vc0 += vgf; + solx = new_sol_x; + soly = new_sol_y; } sol = new Vector(mesh->GetNV()); @@ -451,7 +465,7 @@ void VisualizationSceneVector::NewMeshAndSolution(GridFunction &vgf, Mesh *mc) (*sol)(i) = Vec2Scalar((*solx)(i), (*soly)(i)); } - VisualizationSceneSolution::NewMeshAndSolution(mesh, mesh_coarse, sol, &vgf); + VisualizationSceneSolution::NewMeshAndSolution(mesh, mesh_coarse, sol, vgf); if (autoscale) { diff --git a/lib/vsvector.hpp b/lib/vsvector.hpp index b8c53601..3f4765c9 100644 --- a/lib/vsvector.hpp +++ b/lib/vsvector.hpp @@ -30,6 +30,9 @@ class VisualizationSceneVector : public VisualizationSceneSolution void Init(); + void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol_x, + Vector *new_sol_y, GridFunction *new_u); + void GetRefinedValues(int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr) override; int GetRefinedValuesAndNormals(int i, const IntegrationRule &ir, @@ -50,6 +53,10 @@ class VisualizationSceneVector : public VisualizationSceneSolution public: VisualizationSceneVector(Window &win_); + void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol_x, + Vector *new_sol_y) + { NewMeshAndSolution(new_m, new_mc, new_sol_x, new_sol_y, NULL); } + void NewMeshAndSolution(GridFunction &vgf, Mesh *mc = NULL); virtual ~VisualizationSceneVector(); diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index 1d0ab341..ed1a2537 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -466,6 +466,14 @@ VisualizationSceneVector3d::~VisualizationSceneVector3d() void VisualizationSceneVector3d::NewMeshAndSolution( GridFunction &new_v, Mesh *new_mc) +{ + NewMeshAndSolution(new_v.FESpace()->GetMesh(), new_mc, solx, soly, solz, + &new_v); +} + +void VisualizationSceneVector3d::NewMeshAndSolution( + Mesh *new_m, Mesh *new_mc, Vector *new_sol_x, Vector *new_sol_y, + Vector *new_sol_z, GridFunction *new_v) { delete sol; if (VecGridF) @@ -476,7 +484,6 @@ void VisualizationSceneVector3d::NewMeshAndSolution( delete GridF; delete sfes; } - Mesh *new_m = new_v.FESpace()->GetMesh(); if (mesh->GetNV() != new_m->GetNV()) { delete [] node_pos; @@ -484,7 +491,7 @@ void VisualizationSceneVector3d::NewMeshAndSolution( } Mesh *old_m = mesh; - VecGridF = &new_v; + VecGridF = new_v; mesh = new_m; mesh_coarse = new_mc; @@ -501,21 +508,30 @@ void VisualizationSceneVector3d::NewMeshAndSolution( } } - FiniteElementSpace *new_fes = new_v.FESpace(); FindNodePos(); - sfes = new FiniteElementSpace(mesh, new_fes->FEColl(), 1, - new_fes->GetOrdering()); - GridF = new GridFunction(sfes); + if (new_v) + { + FiniteElementSpace *new_fes = new_v->FESpace(); + sfes = new FiniteElementSpace(mesh, new_fes->FEColl(), 1, + new_fes->GetOrdering()); + GridF = new GridFunction(sfes); - solx = new Vector(mesh->GetNV()); - soly = new Vector(mesh->GetNV()); - solz = new Vector(mesh->GetNV()); + solx = new Vector(mesh->GetNV()); + soly = new Vector(mesh->GetNV()); + solz = new Vector(mesh->GetNV()); - VecGridF->GetNodalValues(*solx, 1); - VecGridF->GetNodalValues(*soly, 2); - VecGridF->GetNodalValues(*solz, 3); + VecGridF->GetNodalValues(*solx, 1); + VecGridF->GetNodalValues(*soly, 2); + VecGridF->GetNodalValues(*solz, 3); + } + else + { + solx = new_sol_x; + soly = new_sol_y; + solz = new_sol_z; + } sol = new Vector(mesh->GetNV()); diff --git a/lib/vsvector3d.hpp b/lib/vsvector3d.hpp index 11bb6423..0784271a 100644 --- a/lib/vsvector3d.hpp +++ b/lib/vsvector3d.hpp @@ -31,6 +31,9 @@ class VisualizationSceneVector3d : public VisualizationSceneSolution3d void Init(); + void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol_x, + Vector *new_sol_y, Vector *new_sol_z, GridFunction *new_u); + Array<int> vflevel; Array<double> dvflevel; @@ -41,6 +44,10 @@ class VisualizationSceneVector3d : public VisualizationSceneSolution3d VisualizationSceneVector3d(Window &win); + void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol_x, + Vector *new_sol_y, Vector *new_sol_z) + { NewMeshAndSolution(new_m, new_mc, new_sol_x, new_sol_y, new_sol_z, NULL); } + void NewMeshAndSolution(GridFunction &new_v, Mesh *new_mc = NULL); virtual ~VisualizationSceneVector3d(); diff --git a/lib/window.cpp b/lib/window.cpp index b058128a..12fb75d4 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -226,7 +226,10 @@ void Window::ResetMeshAndSolution(DataState &ss) } else { - std::cerr << "Not implemented" << std::endl; + // pointer to 'sol' vector is invalidated by the move, so we copy + // the data and use a pointer to the local data + data_state.sol = ss.sol; + vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &data_state.sol); } } else @@ -239,7 +242,12 @@ void Window::ResetMeshAndSolution(DataState &ss) } else { - std::cerr << "Not implemented" << std::endl; + // pointer to 'solu/v' vectors is invalidated by the move, so we + // copy the data and use a pointer to the local data + data_state.solu = ss.solu; + data_state.solv = ss.solv; + vsv->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &data_state.solu, + &data_state.solv); } } } @@ -255,7 +263,10 @@ void Window::ResetMeshAndSolution(DataState &ss) } else { - std::cerr << "Not implemented" << std::endl; + // pointer to 'sol' vector is invalidated by the move, so we copy the data + // and use a pointer to the local data + data_state.sol = ss.sol; + vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &data_state.sol); } } else @@ -270,7 +281,13 @@ void Window::ResetMeshAndSolution(DataState &ss) } else { - std::cerr << "Not implemented" << std::endl; + // pointer to 'solu/v/w' vectors is invalidated by the move, so we + // copy the data and use a pointer to the local data + data_state.solu = ss.solu; + data_state.solv = ss.solv; + data_state.solw = ss.solw; + vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &data_state.solu, + &data_state.solv, &data_state.solw); } } } From cd4a25d94520bc80b48ef593b54ec51d3d83ae52 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 3 Jun 2025 23:19:40 -0700 Subject: [PATCH 57/65] Fixed cycling of vector2scalar function for raw data. --- lib/vsvector.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/vsvector.cpp b/lib/vsvector.cpp index 67fc4157..51cf62e0 100644 --- a/lib/vsvector.cpp +++ b/lib/vsvector.cpp @@ -345,7 +345,7 @@ void VisualizationSceneVector::CycleVec2Scalar(int print) for (i = 0; Vec2Scalar != Vec2ScalarFunctions[i]; i++) ; - if (VecGridF->FESpace()->GetVDim() == 1) + if (VecGridF && VecGridF->FESpace()->GetVDim() == 1) { if (dynamic_cast<const ND_FECollection*>(VecGridF->FESpace()->FEColl())) { @@ -358,10 +358,14 @@ void VisualizationSceneVector::CycleVec2Scalar(int print) i = (i + 1) % 5; } } - else + else if (VecGridF) { i = (i + 1) % 7; } + else + { + i = (i + 1) % 4; + } if (print) { From 1b2930e4bded096246ab415e93e904958f486ad0 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 4 Jun 2025 00:23:37 -0700 Subject: [PATCH 58/65] Changed sol* vectors to unique pointers in DataState. --- lib/data_state.cpp | 87 +++++++++++++++++++++++++++++++++++++------ lib/data_state.hpp | 22 +++++++++-- lib/file_reader.cpp | 22 +++++++---- lib/stream_reader.cpp | 57 +++++++++++++++++----------- lib/vsdata.cpp | 2 +- lib/vssolution.cpp | 5 +-- lib/vsvector.cpp | 4 +- lib/vsvector3d.cpp | 6 +-- lib/window.cpp | 29 ++++----------- 9 files changed, 159 insertions(+), 75 deletions(-) diff --git a/lib/data_state.cpp b/lib/data_state.cpp index 3bc95e53..415b31e4 100644 --- a/lib/data_state.cpp +++ b/lib/data_state.cpp @@ -41,12 +41,6 @@ DataState &DataState::operator=(DataState &&ss) type = ss.type; quad_sol = ss.quad_sol; - - sol = std::move(ss.sol); - solu = std::move(ss.solu); - solv = std::move(ss.solv); - solw = std::move(ss.solw); - normals = std::move(ss.normals); keys = std::move(ss.keys); fix_elem_orient = ss.fix_elem_orient; @@ -70,6 +64,77 @@ void DataState::SetMesh(std::unique_ptr<mfem::Mesh> &&pmesh) if (quad_f && quad_f->GetSpace()->GetMesh() != mesh.get()) { SetQuadFunction(NULL); } } +void DataState::SetScalarData(mfem::Vector new_sol) +{ + internal.grid_f.reset(); + internal.quad_f.reset(); + + if (!sol) + { + internal.sol.reset(new Vector(std::move(new_sol))); + } + else + { + *sol = std::move(new_sol); + } + type = DataState::FieldType::SCALAR; +} + +void DataState::SetNormals(mfem::Vector new_normals) +{ + if (!normals) + { + internal.sol.reset(new Vector(std::move(new_normals))); + } + else + { + *sol = std::move(new_normals); + } +} + +void DataState::SetVectorData(mfem::Vector new_solx, mfem::Vector new_soly) +{ + MFEM_VERIFY(mesh->SpaceDimension() == 2, "Incompatible space dimension"); + + internal.grid_f.reset(); + internal.quad_f.reset(); + + if (!solx || !soly) + { + internal.solx.reset(new Vector(std::move(new_solx))); + internal.soly.reset(new Vector(std::move(new_soly))); + } + else + { + *solx = std::move(new_solx); + *soly = std::move(new_soly); + } + type = DataState::FieldType::VECTOR; +} + +void DataState::SetVectorData(mfem::Vector new_solx, mfem::Vector new_soly, + mfem::Vector new_solz) +{ + MFEM_VERIFY(mesh->SpaceDimension() == 3, "Incompatible space dimension"); + + internal.grid_f.reset(); + internal.quad_f.reset(); + + if (!solx || !soly || !solz) + { + internal.solx.reset(new Vector(std::move(new_solx))); + internal.soly.reset(new Vector(std::move(new_soly))); + internal.solz.reset(new Vector(std::move(new_solz))); + } + else + { + *solx = std::move(new_solx); + *soly = std::move(new_soly); + *solz = std::move(new_solz); + } + type = DataState::FieldType::VECTOR; +} + void DataState::SetGridFunction(mfem::GridFunction *gf, int component) { internal.grid_f.reset(gf); @@ -229,14 +294,14 @@ void DataState::Extrude1DMeshAndSolution() internal.grid_f.reset(grid_f_2d); } - else if (sol.Size() == mesh->GetNV()) + else if (sol) { Vector sol2d(mesh2d->GetNV()); for (int i = 0; i < mesh->GetNV(); i++) { - sol2d(2*i+0) = sol2d(2*i+1) = sol(i); + sol2d(2*i+0) = sol2d(2*i+1) = (*sol)(i); } - sol = sol2d; + *sol = std::move(sol2d); } if (!mesh_quad) { internal.mesh.swap(internal.mesh_quad); } @@ -322,8 +387,8 @@ void DataState::SetMeshSolution() } else // zero solution { - sol.SetSize (mesh -> GetNV()); - sol = 0.0; + internal.sol.reset(new Vector(mesh->GetNV())); + *sol = 0.0; } type = FieldType::MESH; } diff --git a/lib/data_state.hpp b/lib/data_state.hpp index 3ee65235..4f31c326 100644 --- a/lib/data_state.hpp +++ b/lib/data_state.hpp @@ -45,10 +45,10 @@ struct DataState }; private: - friend class StreamReader; - friend class FileReader; struct { + std::unique_ptr<mfem::Vector> sol, solx, soly, solz; + std::unique_ptr<mfem::Vector> normals; std::unique_ptr<mfem::Mesh> mesh; std::unique_ptr<mfem::Mesh> mesh_quad; std::unique_ptr<mfem::GridFunction> grid_f; @@ -63,7 +63,11 @@ struct DataState void SetQuadFunctionSolution(int component = -1); public: - mfem::Vector sol, solu, solv, solw, normals; + const std::unique_ptr<mfem::Vector> &sol{internal.sol}; + const std::unique_ptr<mfem::Vector> &solx{internal.solx}; + const std::unique_ptr<mfem::Vector> &soly{internal.soly}; + const std::unique_ptr<mfem::Vector> &solz{internal.solz}; + const std::unique_ptr<mfem::Vector> &normals{internal.normals}; const std::unique_ptr<mfem::Mesh> &mesh{internal.mesh}; const std::unique_ptr<mfem::Mesh> &mesh_quad{internal.mesh_quad}; const std::unique_ptr<mfem::GridFunction> &grid_f{internal.grid_f}; @@ -92,6 +96,18 @@ struct DataState the same one. */ void SetMesh(std::unique_ptr<mfem::Mesh> &&pmesh); + /// Set scalar data + void SetScalarData(mfem::Vector sol); + + /// Set normals + void SetNormals(mfem::Vector normals); + + /// Set 2D vector data + void SetVectorData(mfem::Vector solx, mfem::Vector soly); + + /// Set 3D vector data + void SetVectorData(mfem::Vector solx, mfem::Vector soly, mfem::Vector solz); + /// Set a grid function (plain pointer version) /** Note that ownership is passed from the caller. @see SetGridFunction(std::unique_ptr<mfem::GridFunction> &&, int ) */ diff --git a/lib/file_reader.cpp b/lib/file_reader.cpp index 7efc897e..3ab35705 100644 --- a/lib/file_reader.cpp +++ b/lib/file_reader.cpp @@ -65,19 +65,27 @@ int FileReader::ReadSerial(FileReader::FileType ft, const char *mesh_file, // get rid of NetGen's info line char buff[128]; solin->getline(buff,128); - data.sol.Load(*solin, data.mesh->GetNV()); - data.type = DataState::FieldType::SCALAR; + Vector sol; + sol.Load(*solin, data.mesh->GetNV()); + data.SetScalarData(std::move(sol)); } break; case FileType::VECTOR_SOL: - data.solu.Load(*solin, data.mesh->GetNV()); - data.solv.Load(*solin, data.mesh->GetNV()); + { + Vector solx, soly, solz; + solx.Load(*solin, data.mesh->GetNV()); + soly.Load(*solin, data.mesh->GetNV()); if (data.mesh->SpaceDimension() == 3) { - data.solw.Load(*solin, data.mesh->GetNV()); + solz.Load(*solin, data.mesh->GetNV()); + data.SetVectorData(std::move(solx), std::move(soly), std::move(solz)); } - data.type = DataState::FieldType::VECTOR; - break; + else + { + data.SetVectorData(std::move(solx), std::move(soly)); + } + } + break; default: cerr << "Unknown file type. Exit" << endl; exit(1); diff --git a/lib/stream_reader.cpp b/lib/stream_reader.cpp index 24b40d85..9d1a06e9 100644 --- a/lib/stream_reader.cpp +++ b/lib/stream_reader.cpp @@ -120,30 +120,42 @@ int StreamReader::ReadStream( switch (cmd) { case Command::Fem2D: - data.type = DataState::FieldType::SCALAR; + { + Vector sol; data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); - data.sol.Load(is, data.mesh->GetNV()); - break; + sol.Load(is, data.mesh->GetNV()); + data.SetScalarData(std::move(sol)); + } + break; case Command::VFem2D: case Command::VFem2D_keys: - data.type = DataState::FieldType::VECTOR; + { + Vector solx, soly; data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); - data.solu.Load(is, data.mesh->GetNV()); - data.solv.Load(is, data.mesh->GetNV()); - break; + solx.Load(is, data.mesh->GetNV()); + soly.Load(is, data.mesh->GetNV()); + data.SetVectorData(std::move(solx), std::move(soly)); + } + break; case Command::Fem3D: - data.type = DataState::FieldType::SCALAR; + { + Vector sol; data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); - data.sol.Load(is, data.mesh->GetNV()); - break; + sol.Load(is, data.mesh->GetNV()); + data.SetScalarData(std::move(sol)); + } + break; case Command::VFem3D: case Command::VFem3D_keys: - data.type = DataState::FieldType::VECTOR; + { + Vector solx, soly, solz; data.SetMesh(new Mesh(is, 0, 0, data.fix_elem_orient)); - data.solu.Load(is, data.mesh->GetNV()); - data.solv.Load(is, data.mesh->GetNV()); - data.solw.Load(is, data.mesh->GetNV()); - break; + solx.Load(is, data.mesh->GetNV()); + soly.Load(is, data.mesh->GetNV()); + solz.Load(is, data.mesh->GetNV()); + data.SetVectorData(std::move(solx), std::move(soly), std::move(solz)); + } + break; case Command::Fem2D_GF: case Command::Fem2D_GF_keys: case Command::VFem2D_GF: @@ -220,8 +232,8 @@ int StreamReader::ReadStream( } data.SetMesh(new Mesh(2, tot_num_vert, tot_num_elem, 0)); - data.sol.SetSize(tot_num_vert); - data.normals.SetSize(3*tot_num_vert); + Vector sol(tot_num_vert); + Vector normals(3*tot_num_vert); int v_off = 0; for (int i = 0; i < num_patches; i++) @@ -231,10 +243,10 @@ int StreamReader::ReadStream( for (int j = 0; j < num_vert; j++) { data.mesh->AddVertex(&verts[6*j]); - data.sol(v_off) = verts[6*j+2]; - data.normals(3*v_off+0) = verts[6*j+3]; - data.normals(3*v_off+1) = verts[6*j+4]; - data.normals(3*v_off+2) = verts[6*j+5]; + sol(v_off) = verts[6*j+2]; + normals(3*v_off+0) = verts[6*j+3]; + normals(3*v_off+1) = verts[6*j+4]; + normals(3*v_off+2) = verts[6*j+5]; v_off++; } @@ -277,7 +289,8 @@ int StreamReader::ReadStream( delete vertices[i]; } - data.type = DataState::FieldType::SCALAR; + data.SetScalarData(std::move(sol)); + data.SetNormals(std::move(normals)); } break; case Command::Max: //dummy diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index 03e1eba1..45733aa3 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -1359,7 +1359,7 @@ VisualizationSceneScalarData::VisualizationSceneScalarData( { mesh = win.data_state.mesh.get(); mesh_coarse = win.data_state.mesh_quad.get(); - sol = &win.data_state.sol; + sol = win.data_state.sol.get(); if (init) { diff --git a/lib/vssolution.cpp b/lib/vssolution.cpp index 09a1db79..0030f202 100644 --- a/lib/vssolution.cpp +++ b/lib/vssolution.cpp @@ -421,10 +421,7 @@ static void KeyF12Pressed() VisualizationSceneSolution::VisualizationSceneSolution( Window &win_, bool init) : VisualizationSceneScalarData(win_, false) { - if (win.data_state.normals.Size() > 0) - { - v_normals = &win.data_state.normals; - } + v_normals = win.data_state.normals.get(); if (win.data_state.grid_f) { diff --git a/lib/vsvector.cpp b/lib/vsvector.cpp index 51cf62e0..8eb20973 100644 --- a/lib/vsvector.cpp +++ b/lib/vsvector.cpp @@ -277,8 +277,8 @@ VisualizationSceneVector::VisualizationSceneVector(Window &win_) else { sol = new Vector(mesh -> GetNV()); - solx = &win.data_state.solu; - soly = &win.data_state.solv; + solx = win.data_state.solx.get(); + soly = win.data_state.soly.get(); } Init(); diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index ed1a2537..2ecbd158 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -369,9 +369,9 @@ VisualizationSceneVector3d::VisualizationSceneVector3d(Window &win_) else { sol = new Vector(mesh->GetNV()); - solx = &win.data_state.solu; - soly = &win.data_state.solv; - solz = &win.data_state.solw; + solx = win.data_state.solx.get(); + soly = win.data_state.soly.get(); + solz = win.data_state.solz.get(); } Init(); diff --git a/lib/window.cpp b/lib/window.cpp index 12fb75d4..e57b4c0d 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -124,7 +124,7 @@ bool Window::GLVisInitVis(StreamCollection input_streams) } else { - mesh_range = data_state.sol.Max() + 1.0; + mesh_range = data_state.sol->Max() + 1.0; } } } @@ -226,10 +226,7 @@ void Window::ResetMeshAndSolution(DataState &ss) } else { - // pointer to 'sol' vector is invalidated by the move, so we copy - // the data and use a pointer to the local data - data_state.sol = ss.sol; - vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &data_state.sol); + vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), ss.sol.get()); } } else @@ -242,12 +239,8 @@ void Window::ResetMeshAndSolution(DataState &ss) } else { - // pointer to 'solu/v' vectors is invalidated by the move, so we - // copy the data and use a pointer to the local data - data_state.solu = ss.solu; - data_state.solv = ss.solv; - vsv->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &data_state.solu, - &data_state.solv); + vsv->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), ss.solx.get(), + ss.soly.get()); } } } @@ -263,10 +256,7 @@ void Window::ResetMeshAndSolution(DataState &ss) } else { - // pointer to 'sol' vector is invalidated by the move, so we copy the data - // and use a pointer to the local data - data_state.sol = ss.sol; - vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &data_state.sol); + vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), ss.sol.get()); } } else @@ -281,13 +271,8 @@ void Window::ResetMeshAndSolution(DataState &ss) } else { - // pointer to 'solu/v/w' vectors is invalidated by the move, so we - // copy the data and use a pointer to the local data - data_state.solu = ss.solu; - data_state.solv = ss.solv; - data_state.solw = ss.solw; - vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &data_state.solu, - &data_state.solv, &data_state.solw); + vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), ss.solx.get(), + ss.soly.get(), ss.solz.get()); } } } From 2f29dd450b83e55e5059ea3617bc5909bac803ad Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 4 Jun 2025 00:45:45 -0700 Subject: [PATCH 59/65] Simplified updates of visualization scenes. --- lib/vsdata.hpp | 3 +++ lib/vssolution.cpp | 14 +++++++--- lib/vssolution.hpp | 7 ++--- lib/vssolution3d.cpp | 14 +++++++--- lib/vssolution3d.hpp | 7 ++--- lib/vsvector.cpp | 11 ++++++-- lib/vsvector.hpp | 8 ++---- lib/vsvector3d.cpp | 15 ++++++++--- lib/vsvector3d.hpp | 8 ++---- lib/window.cpp | 63 +++----------------------------------------- 10 files changed, 55 insertions(+), 95 deletions(-) diff --git a/lib/vsdata.hpp b/lib/vsdata.hpp index 0020abc1..5de68706 100644 --- a/lib/vsdata.hpp +++ b/lib/vsdata.hpp @@ -162,6 +162,9 @@ class VisualizationSceneScalarData : public VisualizationScene virtual ~VisualizationSceneScalarData(); + /// Set a new mesh and solution from the given data state + virtual void NewMeshAndSolution(const DataState &s) = 0; + virtual std::string GetHelpString() const { return ""; } // Determine 'xscale', 'yscale', and 'zscale' using the current bounding diff --git a/lib/vssolution.cpp b/lib/vssolution.cpp index 0030f202..594c0466 100644 --- a/lib/vssolution.cpp +++ b/lib/vssolution.cpp @@ -593,11 +593,17 @@ void VisualizationSceneSolution::ToggleDrawElems() } } -void VisualizationSceneSolution::NewMeshAndSolution( - GridFunction &new_u, Mesh *new_mc) +void VisualizationSceneSolution::NewMeshAndSolution(const DataState &s) { - new_u.GetNodalValues(*sol); - NewMeshAndSolution(new_u.FESpace()->GetMesh(), new_mc, sol, &new_u); + if (rsol && s.grid_f) + { + s.grid_f->GetNodalValues(*sol); + NewMeshAndSolution(s.mesh.get(), s.mesh_quad.get(), sol, s.grid_f.get()); + } + else + { + NewMeshAndSolution(s.mesh.get(), s.mesh_quad.get(), s.sol.get()); + } } void VisualizationSceneSolution::NewMeshAndSolution( diff --git a/lib/vssolution.hpp b/lib/vssolution.hpp index 7583fa08..a6dc4ec7 100644 --- a/lib/vssolution.hpp +++ b/lib/vssolution.hpp @@ -59,7 +59,7 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData void Init(); void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol, - GridFunction *new_u); + GridFunction *new_u = NULL); void FindNewBox(double rx[], double ry[], double rval[]); @@ -95,10 +95,7 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData std::string GetHelpString() const override; - void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol) - { NewMeshAndSolution(new_m, new_mc, new_sol, NULL); } - - void NewMeshAndSolution(GridFunction &new_u, Mesh *new_mc = NULL); + void NewMeshAndSolution(const DataState &s) override; void SetNewScalingFromBox() override; void FindNewBox(bool prepare) override; diff --git a/lib/vssolution3d.cpp b/lib/vssolution3d.cpp index 05d67123..12b501b0 100644 --- a/lib/vssolution3d.cpp +++ b/lib/vssolution3d.cpp @@ -831,11 +831,17 @@ VisualizationSceneSolution3d::~VisualizationSceneSolution3d() delete [] node_pos; } -void VisualizationSceneSolution3d::NewMeshAndSolution( - GridFunction &new_u, Mesh *new_mc) +void VisualizationSceneSolution3d::NewMeshAndSolution(const DataState &s) { - new_u.GetNodalValues(*sol); - NewMeshAndSolution(new_u.FESpace()->GetMesh(), new_mc, sol, &new_u); + if (GridF && s.grid_f) + { + s.grid_f->GetNodalValues(*sol); + NewMeshAndSolution(s.mesh.get(), s.mesh_quad.get(), sol, s.grid_f.get()); + } + else + { + NewMeshAndSolution(s.mesh.get(), s.mesh_quad.get(), s.sol.get()); + } } void VisualizationSceneSolution3d::NewMeshAndSolution( diff --git a/lib/vssolution3d.hpp b/lib/vssolution3d.hpp index b74c665e..d95e916f 100644 --- a/lib/vssolution3d.hpp +++ b/lib/vssolution3d.hpp @@ -48,7 +48,7 @@ class VisualizationSceneSolution3d : public VisualizationSceneScalarData void Init(); void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol, - GridFunction *new_u); + GridFunction *new_u = NULL); void GetFaceNormals(const int FaceNo, const int side, const IntegrationRule &ir, DenseMatrix &normals); @@ -124,10 +124,7 @@ class VisualizationSceneSolution3d : public VisualizationSceneScalarData VisualizationSceneSolution3d(Window &win, bool init = true); - void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol) - { NewMeshAndSolution(new_m, new_mc, new_sol, NULL); } - - void NewMeshAndSolution(GridFunction &new_u, Mesh *new_mc = NULL); + void NewMeshAndSolution(const DataState &s) override; virtual ~VisualizationSceneSolution3d(); diff --git a/lib/vsvector.cpp b/lib/vsvector.cpp index 8eb20973..babc9ba5 100644 --- a/lib/vsvector.cpp +++ b/lib/vsvector.cpp @@ -400,9 +400,16 @@ void VisualizationSceneVector::CycleVec2Scalar(int print) } } -void VisualizationSceneVector::NewMeshAndSolution(GridFunction &vgf, Mesh *mc) +void VisualizationSceneVector::NewMeshAndSolution(const DataState &s) { - NewMeshAndSolution(vgf.FESpace()->GetMesh(), mc, solx, soly, &vgf); + if (VecGridF && s.grid_f) + { + NewMeshAndSolution(s.mesh.get(), s.mesh_quad.get(), solx, soly, s.grid_f.get()); + } + else + { + NewMeshAndSolution(s.mesh.get(), s.mesh_quad.get(), s.solx.get(), s.soly.get()); + } } void VisualizationSceneVector::NewMeshAndSolution( diff --git a/lib/vsvector.hpp b/lib/vsvector.hpp index 3f4765c9..a95214df 100644 --- a/lib/vsvector.hpp +++ b/lib/vsvector.hpp @@ -31,7 +31,7 @@ class VisualizationSceneVector : public VisualizationSceneSolution void Init(); void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol_x, - Vector *new_sol_y, GridFunction *new_u); + Vector *new_sol_y, GridFunction *new_u = NULL); void GetRefinedValues(int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr) override; @@ -53,11 +53,7 @@ class VisualizationSceneVector : public VisualizationSceneSolution public: VisualizationSceneVector(Window &win_); - void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol_x, - Vector *new_sol_y) - { NewMeshAndSolution(new_m, new_mc, new_sol_x, new_sol_y, NULL); } - - void NewMeshAndSolution(GridFunction &vgf, Mesh *mc = NULL); + void NewMeshAndSolution(const DataState &s); virtual ~VisualizationSceneVector(); diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index 2ecbd158..42232ac8 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -464,11 +464,18 @@ VisualizationSceneVector3d::~VisualizationSceneVector3d() } } -void VisualizationSceneVector3d::NewMeshAndSolution( - GridFunction &new_v, Mesh *new_mc) +void VisualizationSceneVector3d::NewMeshAndSolution(const DataState &s) { - NewMeshAndSolution(new_v.FESpace()->GetMesh(), new_mc, solx, soly, solz, - &new_v); + if (VecGridF && s.grid_f) + { + NewMeshAndSolution(s.mesh.get(), s.mesh_quad.get(), solx, soly, solz, + s.grid_f.get()); + } + else + { + NewMeshAndSolution(s.mesh.get(), s.mesh_quad.get(), s.solx.get(), s.soly.get(), + s.solz.get()); + } } void VisualizationSceneVector3d::NewMeshAndSolution( diff --git a/lib/vsvector3d.hpp b/lib/vsvector3d.hpp index 0784271a..ba0323fa 100644 --- a/lib/vsvector3d.hpp +++ b/lib/vsvector3d.hpp @@ -32,7 +32,7 @@ class VisualizationSceneVector3d : public VisualizationSceneSolution3d void Init(); void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol_x, - Vector *new_sol_y, Vector *new_sol_z, GridFunction *new_u); + Vector *new_sol_y, Vector *new_sol_z, GridFunction *new_u = NULL); Array<int> vflevel; Array<double> dvflevel; @@ -44,11 +44,7 @@ class VisualizationSceneVector3d : public VisualizationSceneSolution3d VisualizationSceneVector3d(Window &win); - void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol_x, - Vector *new_sol_y, Vector *new_sol_z) - { NewMeshAndSolution(new_m, new_mc, new_sol_x, new_sol_y, new_sol_z, NULL); } - - void NewMeshAndSolution(GridFunction &new_v, Mesh *new_mc = NULL); + void NewMeshAndSolution(const DataState &s) override; virtual ~VisualizationSceneVector3d(); diff --git a/lib/window.cpp b/lib/window.cpp index e57b4c0d..a591d079 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -214,68 +214,13 @@ bool Window::SetNewMeshAndSolution(DataState new_state) void Window::ResetMeshAndSolution(DataState &ss) { - if (ss.mesh->SpaceDimension() == 2) + if (ss.mesh->SpaceDimension() == 3 && + ss.GetType() == DataState::FieldType::VECTOR) { - if (ss.GetType() != DataState::FieldType::VECTOR) - { - VisualizationSceneSolution *vss = - dynamic_cast<VisualizationSceneSolution *>(internal.vs.get()); - if (ss.grid_f) - { - vss->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); - } - else - { - vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), ss.sol.get()); - } - } - else - { - VisualizationSceneVector *vsv = - dynamic_cast<VisualizationSceneVector *>(internal.vs.get()); - if (ss.grid_f) - { - vsv->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); - } - else - { - vsv->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), ss.solx.get(), - ss.soly.get()); - } - } + ss.ProjectVectorFEGridFunction(); } - else - { - if (ss.GetType() != DataState::FieldType::VECTOR) - { - VisualizationSceneSolution3d *vss = - dynamic_cast<VisualizationSceneSolution3d *>(internal.vs.get()); - if (ss.grid_f) - { - vss->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); - } - else - { - vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), ss.sol.get()); - } - } - else - { - ss.ProjectVectorFEGridFunction(); - VisualizationSceneVector3d *vss = - dynamic_cast<VisualizationSceneVector3d *>(internal.vs.get()); - if (ss.grid_f) - { - vss->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); - } - else - { - vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), ss.solx.get(), - ss.soly.get(), ss.solz.get()); - } - } - } + vs->NewMeshAndSolution(ss); } From a70899005ecb317d40c0855dcc41bb55eef1b34d Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Wed, 4 Jun 2025 00:50:06 -0700 Subject: [PATCH 60/65] Fixed override. --- lib/vsvector.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vsvector.hpp b/lib/vsvector.hpp index a95214df..46bacc3e 100644 --- a/lib/vsvector.hpp +++ b/lib/vsvector.hpp @@ -53,7 +53,7 @@ class VisualizationSceneVector : public VisualizationSceneSolution public: VisualizationSceneVector(Window &win_); - void NewMeshAndSolution(const DataState &s); + void NewMeshAndSolution(const DataState &s) override; virtual ~VisualizationSceneVector(); From 39d4da8312058fcdc27781f566f9b7cda72980ae Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 23 Sep 2025 15:50:59 -0700 Subject: [PATCH 61/65] Updated changelog. --- CHANGELOG | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 15c5e145..342b4bfd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -9,6 +9,19 @@ https://glvis.org +Version 4.4.1 (development) +=================================== + +- Refactored code base enabling automatic generation of the script and stream + command lists (shown as help when an unrecognized option is entered). Other + improvements include: + * Unified window initialization between the app and GLVis-js. + * Unified handling of streams and improved data storage, enabling animation + of all data types. + * Fixed the flag for real attributes of distributed meshes. + * Fixed setting of padding digits for data collections. + * Fixed cycling of the vector-to-scalar function in 2D with raw data. + Version 4.4 released on May 1, 2025 =================================== From 6b08ea0deec61c736b3002e2dee24206ed49cef1 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Thu, 22 May 2025 19:10:15 -0700 Subject: [PATCH 62/65] Removed using namespace std pollution. --- lib/aux_vis.cpp | 1 + lib/aux_vis.hpp | 31 ++++++++++++++------------ lib/font.cpp | 3 +++ lib/font.hpp | 12 +++++----- lib/gl/renderer.cpp | 4 ++-- lib/gl/renderer.hpp | 14 ++++++------ lib/gl/renderer_core.cpp | 2 ++ lib/gl/renderer_core.hpp | 4 ++-- lib/gl/renderer_ff.cpp | 6 ++--- lib/gl/shader.cpp | 4 ++-- lib/gl/types.hpp | 2 -- lib/openglvis.cpp | 17 ++++++++------- lib/palettes_base.cpp | 1 + lib/palettes_base.hpp | 46 +++++++++++++++++++-------------------- lib/script_controller.hpp | 18 +++++++-------- lib/sdl.cpp | 3 +-- lib/sdl_main.cpp | 2 ++ lib/sdl_main.hpp | 18 +++++++-------- lib/threads.hpp | 4 ++-- lib/vsdata.hpp | 12 +++++----- lib/window.cpp | 4 ++-- 21 files changed, 108 insertions(+), 100 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index fda13994..c1488b50 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -37,6 +37,7 @@ #endif using namespace mfem; +using namespace std; static thread_local int visualize = 0; static thread_local VisualizationScene *locscene = NULL; diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index 97286abf..561c7cef 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -134,14 +134,15 @@ float GetLineWidthMS(); void InitFont(); GlVisFont * GetFont(); -bool SetFont(const vector<std::string>& patterns, int height); +bool SetFont(const std::vector<std::string>& patterns, int height); void SetFont(const std::string& fn); void SetUseHiDPI(bool status); -function<string(double)> NumberFormatter(int precision=4, char format='d', - bool showsign=false); -function<string(double)> NumberFormatter(string formatting); -bool isValidNumberFormatting(const string& formatting); + +std::function<std::string(double)> NumberFormatter(int precision=4, + char format='d', bool showsign=false); +std::function<std::string(double)> NumberFormatter(std::string formatting); +bool isValidNumberFormatting(const std::string& formatting); // This is a helper function for prompting the user for inputs. The benefit // over using just `cin >> input` is that you can specify a type and optionally @@ -149,22 +150,23 @@ bool isValidNumberFormatting(const string& formatting); // True function. If the input cannot be type casted to the expected type, or // if it fails the validation, the user is asked again for a new input. template <typename T> -T prompt(const string question, +T prompt(const std::string question, const T* default_value = nullptr, -function<bool(T)> validator = [](T) { return true; }) +std::function<bool(T)> validator = [](T) { return true; }) { T input; - string strInput; + std::string strInput; while (true) { - cout << question << " "; - getline(cin, strInput); - stringstream buf(strInput); + std::cout << question << " "; + std::getline(std::cin, strInput); + std::stringstream buf(strInput); if (strInput.empty() && default_value != nullptr) { - cout << "Input empty. Using default value: " << *default_value << endl; + std::cout << "Input empty. Using default value: " << *default_value + << std::endl; return *default_value; } @@ -176,12 +178,13 @@ function<bool(T)> validator = [](T) { return true; }) } else { - cout << "Input is not valid. Please try again." << endl; + std::cout << "Input is not valid. Please try again." << std::endl; } } else { - cout << "Input can not be casted to expected type. Please try again." << endl; + std::cout << "Input can not be casted to expected type. Please try again." + << std::endl; } } return input; diff --git a/lib/font.cpp b/lib/font.cpp index 74ca1bdb..5f041eae 100644 --- a/lib/font.cpp +++ b/lib/font.cpp @@ -14,6 +14,9 @@ #include "font.hpp" #include "aux_vis.hpp" +using std::cout; +using std::endl; + struct vert_tex2d { float x, y; diff --git a/lib/font.hpp b/lib/font.hpp index 24ec2873..619b09f3 100644 --- a/lib/font.hpp +++ b/lib/font.hpp @@ -21,15 +21,13 @@ #include "gl/platform_gl.hpp" -using namespace std; - class GlVisFont { public: struct glyph { - uint32_t w, h; - int32_t bear_x, bear_y; + std::uint32_t w, h; + std::int32_t bear_x, bear_y; float adv_x, adv_y; float tex_x; }; @@ -42,7 +40,7 @@ class GlVisFont glyph font_chars[256]; float tex_w; float tex_h; - uint32_t font_tex; + std::uint32_t font_tex; FT_Library library; FT_Face face; @@ -53,7 +51,7 @@ class GlVisFont const glyph &GetTexChar(char c) const { - return font_chars[(uint8_t) c]; + return font_chars[(std::uint8_t) c]; } /// Get the width and height of the bounding box containing the rendered text @@ -66,7 +64,7 @@ class GlVisFont { if (FT_Init_FreeType(&library)) { - cout << "GLVis: Can not initialize FreeType library!" << endl; + std::cout << "GLVis: Can not initialize FreeType library!" << std::endl; } init = true; } diff --git a/lib/gl/renderer.cpp b/lib/gl/renderer.cpp index ad9421ef..03ba46e9 100644 --- a/lib/gl/renderer.cpp +++ b/lib/gl/renderer.cpp @@ -148,7 +148,7 @@ void MeshRenderer::render(const RenderQueue& queue) if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - cerr << "Unable to create multisampled renderbuffer." << flush; + std::cerr << "Unable to create multisampled renderbuffer." << std::flush; glDeleteFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -268,7 +268,7 @@ void MeshRenderer::render(const RenderQueue& queue) if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - cerr << "Unable to create resolve renderbuffer." << endl; + std::cerr << "Unable to create resolve renderbuffer." << std::endl; glBindFramebuffer(GL_FRAMEBUFFER, 0); } diff --git a/lib/gl/renderer.hpp b/lib/gl/renderer.hpp index f0c9b524..5d15da78 100644 --- a/lib/gl/renderer.hpp +++ b/lib/gl/renderer.hpp @@ -55,11 +55,11 @@ struct RenderParams bool contains_translucent; }; -typedef vector<pair<RenderParams, GlDrawable*>> RenderQueue; +typedef std::vector<std::pair<RenderParams, GlDrawable*>> RenderQueue; struct SceneInfo { - vector<GlDrawable*> needs_buffering; + std::vector<GlDrawable*> needs_buffering; RenderQueue queue; }; @@ -88,9 +88,9 @@ struct FeedbackText struct CaptureBuffer { - vector<FeedbackVertex> lines; - vector<FeedbackVertex> triangles; - vector<FeedbackText> text; + std::vector<FeedbackVertex> lines; + std::vector<FeedbackVertex> triangles; + std::vector<FeedbackText> text; }; // OpenGL device interface representing rendering capabilities @@ -195,7 +195,7 @@ class GLDevice class MeshRenderer { - unique_ptr<GLDevice> device; + std::unique_ptr<GLDevice> device; bool msaa_enable; int msaa_samples; GLuint color_tex, alpha_tex, font_tex; @@ -243,7 +243,7 @@ class MeshRenderer std::cerr << "GL_MAX_SAMPLES = " << msaa_samples << " but requested " << samples << "x MSAA. "; std::cerr << "Setting antialiasing mode to " - << msaa_samples << "x MSAA." << endl; + << msaa_samples << "x MSAA." << std::endl; } else { diff --git a/lib/gl/renderer_core.cpp b/lib/gl/renderer_core.cpp index 4b026307..3e4af146 100644 --- a/lib/gl/renderer_core.cpp +++ b/lib/gl/renderer_core.cpp @@ -40,6 +40,8 @@ const std::string PRINTING_FS = namespace gl3 { +using namespace std; + const std::vector<std::string> CoreGLDevice::unif_list = { "useClipPlane", diff --git a/lib/gl/renderer_core.hpp b/lib/gl/renderer_core.hpp index 41f41ab2..f3ec9872 100644 --- a/lib/gl/renderer_core.hpp +++ b/lib/gl/renderer_core.hpp @@ -68,9 +68,9 @@ class CoreGLDevice : public GLDevice void drawDeviceBufferImpl(GLenum shape, int count, bool indexed); void processTriangleXfbBuffer(CaptureBuffer& cbuf, - const vector<ShaderXfbVertex>& verts); + const std::vector<ShaderXfbVertex>& verts); void processLineXfbBuffer(CaptureBuffer& cbuf, - const vector<ShaderXfbVertex>& verts); + const std::vector<ShaderXfbVertex>& verts); public: CoreGLDevice() diff --git a/lib/gl/renderer_ff.cpp b/lib/gl/renderer_ff.cpp index e507acb6..a4f023bb 100644 --- a/lib/gl/renderer_ff.cpp +++ b/lib/gl/renderer_ff.cpp @@ -192,7 +192,7 @@ void FFGLDevice::bufferToDevice(array_layout layout, IVertexBuffer& buf) bufferFFDeviceImpl(static_cast<const VertexBuffer<VertexNormTex>&>(buf)); break; default: - cerr << "WARNING: Unhandled vertex layout " << layout << endl; + std::cerr << "WARNING: Unhandled vertex layout " << layout << std::endl; } } @@ -232,7 +232,7 @@ void FFGLDevice::bufferToDevice(array_layout layout, IIndexedBuffer& buf) bufferFFDeviceImpl(static_cast<const IndexedVertexBuffer<VertexNormTex>&>(buf)); break; default: - cerr << "WARNING: Unhandled vertex layout " << layout << endl; + std::cerr << "WARNING: Unhandled vertex layout " << layout << std::endl; } } @@ -370,7 +370,7 @@ void FFGLDevice::captureXfbBuffer(PaletteState& pal, CaptureBuffer& cbuf, return; } // allocate feedback buffer - vector<float> xfb_buf; + std::vector<float> xfb_buf; xfb_buf.resize(sizebuf); glFeedbackBuffer(sizebuf, fbType, xfb_buf.data()); // draw with feedback capture diff --git a/lib/gl/shader.cpp b/lib/gl/shader.cpp index 9f72aa84..46c0a676 100644 --- a/lib/gl/shader.cpp +++ b/lib/gl/shader.cpp @@ -269,7 +269,7 @@ bool ShaderProgram::linkShaders(const std::vector<GLuint>& shaders) glGetProgramiv(program_id, GL_LINK_STATUS, &stat); if (stat == GL_FALSE) { - cerr << "fatal: Shader linking failed" << endl; + std::cerr << "fatal: Shader linking failed" << std::endl; } return (stat == GL_TRUE); } @@ -283,7 +283,7 @@ void ShaderProgram::mapShaderUniforms() for (int i = 0; i < num_unifs; i++) { - vector<char> unif_buf(max_unif_len+1); + std::vector<char> unif_buf(max_unif_len+1); GLsizei name_length; GLint gl_size; GLenum gl_type; diff --git a/lib/gl/types.hpp b/lib/gl/types.hpp index 43cd9563..4d8beeb1 100644 --- a/lib/gl/types.hpp +++ b/lib/gl/types.hpp @@ -33,8 +33,6 @@ #include "platform_gl.hpp" -using namespace std; - class VisualizationScene; namespace gl3 diff --git a/lib/openglvis.cpp b/lib/openglvis.cpp index 6d131896..9b066a38 100644 --- a/lib/openglvis.cpp +++ b/lib/openglvis.cpp @@ -15,6 +15,7 @@ #include "aux_vis.hpp" using namespace mfem; +using std::cout; const int NUM_MATERIALS = 5; extern Material materials[5]; @@ -481,7 +482,7 @@ VisualizationScene::AddPaletteMaterial(glTF_Builder &bld) /* wrapT: */ glTF_Builder::wrap_type::CLAMP_TO_EDGE); // create palette image const int palette_size = palette.GetNumColors(); - vector<array<float,4>> palette_data = palette.GetPalette()->GetData(); + std::vector<std::array<float,4>> palette_data = palette.GetPalette()->GetData(); #if 0 glGetTextureImage( palette.GetColorTexture(), 0, @@ -565,7 +566,7 @@ VisualizationScene::AddPaletteLinesMaterial( } glTF_Builder::node_id -VisualizationScene::AddModelNode(glTF_Builder &bld, const string &nodeName) +VisualizationScene::AddModelNode(glTF_Builder &bld, const std::string &nodeName) { auto new_node = bld.addNode(nodeName); // Coordinate system switch: (x,y,z) -> (x,z,-y). @@ -584,12 +585,12 @@ VisualizationScene::AddModelNode(glTF_Builder &bld, const string &nodeName) // Used in VisualizationScene::AddTriangles() below. void minmax(const float *data, size_t components, size_t stride, size_t count, - vector<float> &mins, vector<float> &maxs) + std::vector<float> &mins, std::vector<float> &maxs) { if (count == 0) { - mins.assign(components, +numeric_limits<float>::infinity()); - maxs.assign(components, -numeric_limits<float>::infinity()); + mins.assign(components, +std::numeric_limits<float>::infinity()); + maxs.assign(components, -std::numeric_limits<float>::infinity()); return; } mins.resize(components); @@ -654,7 +655,7 @@ int VisualizationScene::AddTriangles(glTF_Builder &bld, } const gl3::IVertexBuffer *surf_buf = nullptr; const gl3::IIndexedBuffer *surf_ibuf = nullptr; - const vector<int> *surf_indices = nullptr; + const std::vector<int> *surf_indices = nullptr; if (num_ibuf) { surf_buf = surf_ibuf = gl_drawable.indexed_buffers[ibuf_layout][1].get(); @@ -669,7 +670,7 @@ int VisualizationScene::AddTriangles(glTF_Builder &bld, const size_t surf_vertices_stride = surf_buf->getStride(); // in bytes const float *surf_vertices_data = reinterpret_cast<const float *>(surf_buf->getData()); - vector<float> vmins, vmaxs; + std::vector<float> vmins, vmaxs; int components = surf_vertices_stride/sizeof(float); switch (buf_layout) { @@ -884,7 +885,7 @@ int VisualizationScene::AddLines(glTF_Builder &bld, const size_t lines_vertices_stride = lines_buf->getStride(); // in bytes const float *lines_vertices_data = reinterpret_cast<const float *>(lines_buf->getData()); - vector<float> vmins, vmaxs; + std::vector<float> vmins, vmaxs; int components = lines_vertices_stride/sizeof(float); switch (buf_layout) { diff --git a/lib/palettes_base.cpp b/lib/palettes_base.cpp index 1393c2d2..28c85d43 100644 --- a/lib/palettes_base.cpp +++ b/lib/palettes_base.cpp @@ -13,6 +13,7 @@ #include "palettes_default.cpp" #include "gl/renderer.hpp" +using namespace std; void RGBAf::Print(ostream& os) const { diff --git a/lib/palettes_base.hpp b/lib/palettes_base.hpp index 7ecd437f..61df7859 100644 --- a/lib/palettes_base.hpp +++ b/lib/palettes_base.hpp @@ -22,8 +22,6 @@ #include <vector> #include <iomanip> -using namespace std; - struct RGBAf { float r, g, b, a; @@ -31,31 +29,31 @@ struct RGBAf constexpr RGBAf(float r = 0.0, float g = 0.0, float b = 0.0, float a = 1.0) : r(r), g(g), b(b), a(a) {} - void Print(ostream& os = cout) const; + void Print(std::ostream& os = std::cout) const; - array<float, 4> AsArray() const { return {r, g, b, a}; } + std::array<float, 4> AsArray() const { return {r, g, b, a}; } }; class Palette { public: - const string name; + const std::string name; /// Constructors - Palette(const string& name) : name(name) {} + Palette(const std::string& name) : name(name) {} /// Constructor from vector of RGBAf - Palette(const string& name, const vector<RGBAf>& colors) + Palette(const std::string& name, const std::vector<RGBAf>& colors) : name(name), colors(colors) {} /// Constructor from Nx3 array template <size_t N> - Palette(const string& name, const array<array<float,3>,N>& arr); + Palette(const std::string& name, const std::array<std::array<float,3>,N>& arr); /// Constructor from Nx4 array template <size_t N> - Palette(const string& name, const array<array<float,4>,N>& arr); + Palette(const std::string& name, const std::array<std::array<float,4>,N>& arr); /// Get size int Size() const { return colors.size(); } @@ -64,25 +62,25 @@ class Palette void AddColor(float r, float g, float b, float a = 1.0); /// Print each color of this palette to a stream - void Print(ostream& os = cout) const; + void Print(std::ostream& os = std::cout) const; /// Get color at index i (optionally, use reversed order) RGBAf Color(int i, bool reversed = false) const; /// Get all colors as a vector of float arrays - vector<array<float,4>> GetData(bool reversed = false) const; + std::vector<std::array<float,4>> GetData(bool reversed = false) const; /// Are any alpha != 1.0? bool IsTranslucent() const; private: - vector<RGBAf> colors; + std::vector<RGBAf> colors; }; -using TexHandle = gl3::resource::TextureHandle; /// Generates the texture data for a given palette, to be used in OpenGL class Texture { + using TexHandle = gl3::resource::TextureHandle; public: // What type of texture is this (discrete, smooth, alphamap) enum class TextureType @@ -147,8 +145,8 @@ class Texture static void InitStaticGL(); /// Generate alpha/regular texture data - vector<float> GenerateAlphaTextureData(); - vector<array<float,4>> GenerateTextureData(); + std::vector<float> GenerateAlphaTextureData(); + std::vector<std::array<float,4>> GenerateTextureData(); /// Set the number of cycles void SetCycles(int cycles); @@ -173,10 +171,10 @@ std::unique_ptr<T> as_unique(Args&&... args) class PaletteRegistry { private: - vector<unique_ptr<Palette>> palettes; + std::vector<std::unique_ptr<Palette>> palettes; /// Find the index of a palette by name - int GetIndexByName(const string& name) const; + int GetIndexByName(const std::string& name) const; public: /// Empty constructor @@ -184,28 +182,28 @@ class PaletteRegistry /// Constructor via a const vector of Palettes; if name already exists, skip /// Used for loading compiled palettes (i.e. `palettes_default.cpp`) - PaletteRegistry(const vector<Palette>& paletteRefs); + PaletteRegistry(const std::vector<Palette>& paletteRefs); /// Adds an existing palette to the registry void AddPalette(Palette& palette); /// Create a new palette with the given name and add it to the registry - void AddPalette(const string& name); + void AddPalette(const std::string& name); /// Returns true if name is unique - bool IsNameUnique(const string& name) const; + bool IsNameUnique(const std::string& name) const; /// Get a palette pointer by index; if not found, returns last palette Palette* Get(int index) const; /// Get a palette pointer by name; if not found, returns last palette - Palette* Get(const string& name) const; + Palette* Get(const std::string& name) const; /// Prints a summary (index + name) of all palettes - void PrintSummary(ostream& os = cout) const; + void PrintSummary(std::ostream& os = std::cout) const; /// Prints all colors for all palettes - void PrintAll(ostream& os = cout) const; + void PrintAll(std::ostream& os = std::cout) const; /// Number of palettes in the registry int NumPalettes() const { return palettes.size(); } @@ -218,7 +216,7 @@ class PaletteRegistry ... see `share/palettes-crameri.txt` for an example */ - void Load(const string& palette_filename); + void Load(const std::string& palette_filename); }; diff --git a/lib/script_controller.hpp b/lib/script_controller.hpp index 99b173a5..eb3e3d62 100644 --- a/lib/script_controller.hpp +++ b/lib/script_controller.hpp @@ -24,22 +24,22 @@ class ScriptController { Window win; - string dc_protocol = string_default; + std::string dc_protocol = string_default; int dc_cycle = 0; - istream *script = NULL; + std::istream *script = NULL; int scr_running = 0; int scr_level = 0; std::unique_ptr<mfem::Vector> init_nodes; double scr_min_val, scr_max_val; - static int ScriptReadSolution(istream &scr, DataState &state); - static int ScriptReadQuadrature(istream &scr, DataState &state); - static int ScriptReadParSolution(istream &scr, DataState &state); - static int ScriptReadParQuadrature(istream &scr, DataState &state); - int ScriptReadDisplMesh(istream &scr, DataState &state); - int ScriptReadDataColl(istream &scr, DataState &state, bool mesh_only = true, - bool quad = false); + static int ScriptReadSolution(std::istream &scr, DataState &state); + static int ScriptReadQuadrature(std::istream &scr, DataState &state); + static int ScriptReadParSolution(std::istream &scr, DataState &state); + static int ScriptReadParQuadrature(std::istream &scr, DataState &state); + int ScriptReadDisplMesh(std::istream &scr, DataState &state); + int ScriptReadDataColl(std::istream &scr, DataState &state, + bool mesh_only = true, bool quad = false); //key handlers using thread-local singleton static thread_local ScriptController *script_ctrl; diff --git a/lib/sdl.cpp b/lib/sdl.cpp index 3131d757..140784cc 100644 --- a/lib/sdl.cpp +++ b/lib/sdl.cpp @@ -24,8 +24,7 @@ #include "sdl_mac.hpp" #endif -using std::cerr; -using std::endl; +using namespace std; #ifdef GLVIS_DEBUG #define PRINT_DEBUG(s) std::cerr << s diff --git a/lib/sdl_main.cpp b/lib/sdl_main.cpp index d9a6941a..1f394e17 100644 --- a/lib/sdl_main.cpp +++ b/lib/sdl_main.cpp @@ -30,6 +30,8 @@ extern int GetMultisample(); extern bool wndUseHiDPI; +using namespace std; + struct SdlMainThread::CreateWindowCmd { SdlWindow* wnd; diff --git a/lib/sdl_main.hpp b/lib/sdl_main.hpp index d5b627c2..f4d9401c 100644 --- a/lib/sdl_main.hpp +++ b/lib/sdl_main.hpp @@ -113,14 +113,14 @@ class SdlMainThread // A flag indicating whether the main loop will *begin* terminating bool terminating {false}; - unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> bg_wnd{nullptr, SDL_DestroyWindow}; + std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> bg_wnd{nullptr, SDL_DestroyWindow}; // ------------------------------------------------------------------------- // Objects for handling passing of window control commands to the main event // loop. - mutex window_cmd_mtx; - vector<SdlCtrlCommand> window_cmds; + std::mutex window_cmd_mtx; + std::vector<SdlCtrlCommand> window_cmds; int num_windows {-1}; // -1: waiting for window to be created @@ -128,17 +128,17 @@ class SdlMainThread // Objects for handling dispatching events from the main event loop to // worker threads. - unordered_map<int, SdlWindow*> hwnd_to_window; - unordered_map<int, vector<SDL_Event>> wnd_events; + std::unordered_map<int, SdlWindow*> hwnd_to_window; + std::unordered_map<int, std::vector<SDL_Event>> wnd_events; std::set<SDL_FingerID> fingers; bool disable_mouse {false}; - mutex gl_ctx_mtx; + std::mutex gl_ctx_mtx; - mutex event_mtx; - condition_variable event_cv; + std::mutex event_mtx; + std::condition_variable event_cv; bool try_create_platform{false}; - unique_ptr<SdlNativePlatform> platform; + std::unique_ptr<SdlNativePlatform> platform; int title_height_offset {0}; }; diff --git a/lib/threads.hpp b/lib/threads.hpp index c63e3e82..136ecbdb 100644 --- a/lib/threads.hpp +++ b/lib/threads.hpp @@ -125,8 +125,8 @@ class GLVisCommand int Palette(int pal); int PaletteRepeat(int n); int Levellines(double minv, double maxv, int number); - int AxisNumberFormat(string formatting); - int ColorbarNumberFormat(string formatting); + int AxisNumberFormat(std::string formatting); + int ColorbarNumberFormat(std::string formatting); int Camera(const double cam[]); int Autopause(const char *mode); diff --git a/lib/vsdata.hpp b/lib/vsdata.hpp index 5de68706..2175e45b 100644 --- a/lib/vsdata.hpp +++ b/lib/vsdata.hpp @@ -81,10 +81,12 @@ class VisualizationSceneScalarData : public VisualizationScene int auto_ref_max, auto_ref_min_surf_vert, auto_ref_max_surf_vert; // Formatter for axes & colorbar numbers. Set defaults. - function<string(double)> axis_formatter = NumberFormatter(4, 'd', false); - function<string(double)> colorbar_formatter = NumberFormatter(4, 'd', false); + std::function<std::string(double)> axis_formatter + = NumberFormatter(4, 'd', false); + std::function<std::string(double)> colorbar_formatter + = NumberFormatter(4, 'd', false); - vector<gl3::GlDrawable*> updated_bufs; + std::vector<gl3::GlDrawable*> updated_bufs; gl3::GlDrawable axes_buf; gl3::GlDrawable coord_cross_buf; gl3::GlDrawable color_bar; @@ -280,7 +282,7 @@ class VisualizationSceneScalarData : public VisualizationScene void PrepareCaption(); void SetColorbarNumberFormat(int precision, char format, bool showsign); - void SetColorbarNumberFormat(string formatting); + void SetColorbarNumberFormat(std::string formatting); void PrepareColorBar(double minval, double maxval, Array<double> * level = NULL, @@ -289,7 +291,7 @@ class VisualizationSceneScalarData : public VisualizationScene void SetAxisLabels(const char * a_x, const char * a_y, const char * a_z); void SetAxisNumberFormat(int precision, char format, bool showsign); - void SetAxisNumberFormat(string formatting); + void SetAxisNumberFormat(std::string formatting); void PrepareAxes(); void ToggleDrawAxes() diff --git a/lib/window.cpp b/lib/window.cpp index a591d079..7b515469 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -52,7 +52,7 @@ bool Window::GLVisInitVis(StreamCollection input_streams) window_h)); if (!wnd) { - cerr << "Initializing the visualization failed." << endl; + std::cerr << "Initializing the visualization failed." << std::endl; return false; } @@ -183,7 +183,7 @@ void Window::GLVisStartVis() internal.glvis_command.reset(); } #endif - cout << "GLVis window closed." << endl; + std::cout << "GLVis window closed." << std::endl; } void Window::SwitchQuadSolution(DataState::QuadSolution quad_type) From a9235edf50c79cd45ebeb193face01cc79cf928d Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 13 Jan 2026 11:53:46 -0800 Subject: [PATCH 63/65] Post-merge fix of typo. --- makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefile b/makefile index cce90e01..542d216d 100644 --- a/makefile +++ b/makefile @@ -255,7 +255,7 @@ ALL_SOURCE_FILES = \ lib/coll_reader.cpp lib/data_state.cpp lib/file_reader.cpp \ lib/font.cpp lib/gl2ps.c lib/gltf.cpp lib/material.cpp \ lib/openglvis.cpp lib/palettes_base.cpp lib/palettes.cpp \ - lib/palettes_default.cpplib/sdl.cpp lib/script_controller.cpp \ + lib/palettes_default.cpp lib/sdl.cpp lib/script_controller.cpp \ lib/sdl_helper.cpp lib/sdl_main.cpp lib/sdl_windows.cpp \ lib/sdl_x11.cpp lib/stream_reader.cpp lib/threads.cpp lib/vsdata.cpp \ lib/vssolution.cpp lib/vssolution3d.cpp lib/vsvector.cpp \ From f39abeedb4437b12de6ac77408c7895a22ea9c5d Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Tue, 13 Jan 2026 11:55:44 -0800 Subject: [PATCH 64/65] Reorder in makefile. --- makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefile b/makefile index 542d216d..1b4d5ad0 100644 --- a/makefile +++ b/makefile @@ -255,7 +255,7 @@ ALL_SOURCE_FILES = \ lib/coll_reader.cpp lib/data_state.cpp lib/file_reader.cpp \ lib/font.cpp lib/gl2ps.c lib/gltf.cpp lib/material.cpp \ lib/openglvis.cpp lib/palettes_base.cpp lib/palettes.cpp \ - lib/palettes_default.cpp lib/sdl.cpp lib/script_controller.cpp \ + lib/palettes_default.cpp lib/script_controller.cpp lib/sdl.cpp \ lib/sdl_helper.cpp lib/sdl_main.cpp lib/sdl_windows.cpp \ lib/sdl_x11.cpp lib/stream_reader.cpp lib/threads.cpp lib/vsdata.cpp \ lib/vssolution.cpp lib/vssolution3d.cpp lib/vsvector.cpp \ From 8f22066fc527da6d58f1af8e2dc210f086c72525 Mon Sep 17 00:00:00 2001 From: Jan Nikl <nikl1@llnl.gov> Date: Mon, 26 Jan 2026 11:34:27 -0800 Subject: [PATCH 65/65] Removed SetDataOffsets(). --- lib/vsdata.cpp | 1 + lib/vsdata.hpp | 5 ----- lib/window.cpp | 4 ---- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index bedbf564..c811e5ac 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -1359,6 +1359,7 @@ VisualizationSceneScalarData::VisualizationSceneScalarData( mesh = win.data_state.mesh.get(); mesh_coarse = win.data_state.mesh_quad.get(); sol = win.data_state.sol.get(); + offsets = win.data_state.offsets.get(); if (init) { diff --git a/lib/vsdata.hpp b/lib/vsdata.hpp index 05d24697..f7ad8481 100644 --- a/lib/vsdata.hpp +++ b/lib/vsdata.hpp @@ -222,11 +222,6 @@ class VisualizationSceneScalarData : public VisualizationScene mfem::Mesh *GetMesh() { return mesh; } - void SetDataOffsets(const DataState::Offsets *data_offsets) - { - offsets = data_offsets; - } - gl3::SceneInfo GetSceneObjs() override; void ProcessUpdatedBufs(gl3::SceneInfo& scene); diff --git a/lib/window.cpp b/lib/window.cpp index 5a8e6ae1..7b515469 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -91,8 +91,6 @@ bool Window::GLVisInitVis(StreamCollection input_streams) // the 'jet-like' palette is used in 2D, see vssolution.cpp). vs->palette.SetIndex(4); } - // Window structure with DataState could allow to remove this call - vs->SetDataOffsets(data_state.offsets.get()); } else if (data_state.mesh->SpaceDimension() == 3) { @@ -135,8 +133,6 @@ bool Window::GLVisInitVis(StreamCollection input_streams) if (data_state.mesh->SpaceDimension() == 2) { internal.vs.reset(new VisualizationSceneVector(*this)); - // Window structure with DataState could allow to remove this call - vs->SetDataOffsets(data_state.offsets.get()); } else if (data_state.mesh->SpaceDimension() == 3) {