diff --git a/CHANGELOG b/CHANGELOG index 52dec42d..ef9ee709 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -9,8 +9,18 @@ http://glvis.org -Version 3.2, released on June 30, 2016 -====================================== +Version 3.3, released on Jan 28, 2017 +===================================== + +- Added the ability to change the axis labels displayed with the coordinate + cross in the lower left corner. They can be set with the new 'axis_labels' + socket command, for example: sol_sock << "axis_labels 'u' 'v' 'w'\n"; + +- With the corresponding version of MFEM, GLVis now supports gz-compressed + files and socket streams. + +Version 3.2, released on Jun 30, 2016 +===================================== - Added support for secure socket connections based on the GnuTLS library through MFEM. This option may be useful in multi-user environment to prevent diff --git a/glvis.cpp b/glvis.cpp index 60b5f4fb..b04f5849 100644 --- a/glvis.cpp +++ b/glvis.cpp @@ -510,7 +510,7 @@ int ScriptReadSolution(istream &scr, Mesh **mp, GridFunction **sp) // read the mesh scr >> ws >> word; // mesh filename (can't contain spaces) { - ifstream imesh(word.c_str()); + named_ifgzstream imesh(word.c_str()); if (!imesh) { cout << "Can not open mesh file: " << word << endl; @@ -523,7 +523,7 @@ int ScriptReadSolution(istream &scr, Mesh **mp, GridFunction **sp) // read the solution (GridFunction) scr >> ws >> word; { - ifstream isol(word.c_str()); + ifgzstream isol(word.c_str()); if (!isol) { cout << "Can not open solution file: " << word << endl; @@ -581,7 +581,7 @@ int ScriptReadDisplMesh(istream &scr, Mesh **mp, GridFunction **sp) cout << "Script: mesh: " << flush; scr >> ws >> word; { - ifstream imesh(word.c_str()); + named_ifgzstream imesh(word.c_str()); if (!imesh) { cout << "Can not open mesh file: " << word << endl; @@ -1387,7 +1387,12 @@ int main (int argc, char *argv[]) #endif while (1) { - while (server.accept(*isock) < 0); + while (server.accept(*isock) < 0) + { +#ifdef GLVIS_DEBUG + cout << "GLVis: server.accept(...) failed." << endl; +#endif + } *isock >> data_type >> ws; @@ -1408,7 +1413,38 @@ int main (int argc, char *argv[]) cout << "new connection: parallel " << nproc << ' ' << proc << endl; #endif - input_streams.SetSize(nproc); + if (np == 0) + { + if (nproc <= 0) + { + cout << "Invalid number of processors: " << nproc << endl; + mfem_error(); + } + input_streams.SetSize(nproc); + input_streams = NULL; + } + else + { + if (nproc != input_streams.Size()) + { + cout << "Unexpected number of processors: " << nproc + << ", expected: " << input_streams.Size() << endl; + mfem_error(); + } + } + if (0 > proc || proc >= nproc) + { + cout << "Invalid processor rank: " << proc + << ", number of processors: " << nproc << endl; + mfem_error(); + } + if (input_streams[proc]) + { + cout << "Second connection attempt from processor rank: " + << proc << endl; + mfem_error(); + } + input_streams[proc] = isock; #ifndef MFEM_USE_GNUTLS isock = new socketstream; @@ -1422,8 +1458,19 @@ int main (int argc, char *argv[]) break; } // read next available socket stream - while (server.accept(*isock) < 0); + while (server.accept(*isock) < 0) + { +#ifdef GLVIS_DEBUG + cout << "GLVis: server.accept(...) failed." << endl; +#endif + } *isock >> data_type >> ws; // "parallel" + if (data_type != "parallel") + { + cout << "Expected keyword \"parallel\", got \"" << data_type + << '"' << endl; + mfem_error(); + } } while (1); } @@ -1702,9 +1749,8 @@ void ReadSerial() if (is_gf || (input & 4) || (input & 8)) { - ifstream solin; // get the solution from file - solin.open(sol_file); + ifgzstream solin(sol_file); if (!solin) { cerr << "Can not open solution file " << sol_file << ". Exit.\n"; @@ -1867,12 +1913,11 @@ int ReadParMeshAndGridFunction(int np, const char *mesh_prefix, Array mesh_array; mesh_array.SetSize(np); - ifstream meshfile; for (int p = 0; p < np; p++) { ostringstream fname; fname << mesh_prefix << '.' << setfill('0') << setw(pad_digits) << p; - meshfile.open(fname.str().c_str()); + named_ifgzstream meshfile(fname.str().c_str()); if (!meshfile) { cerr << "Can not open mesh file: " << fname.str().c_str() @@ -1896,19 +1941,17 @@ int ReadParMeshAndGridFunction(int np, const char *mesh_prefix, mesh_array[p]->GetBdrElement(i)->SetAttribute(p+1); } } - meshfile.close(); } *mesh_p = new Mesh(mesh_array, np); if (sol_prefix && sol_p) { Array gf_array(np); - ifstream solfile; for (int p = 0; p < np; p++) { ostringstream fname; fname << sol_prefix << '.' << setfill('0') << setw(pad_digits) << p; - solfile.open(fname.str().c_str()); + ifgzstream solfile(fname.str().c_str()); if (!solfile) { cerr << "Can not open solution file " << fname.str().c_str() @@ -1926,7 +1969,6 @@ int ReadParMeshAndGridFunction(int np, const char *mesh_prefix, return 2; } gf_array[p] = new GridFunction(mesh_array[p], solfile); - solfile.close(); } *sol_p = new GridFunction(*mesh_p, gf_array, np); diff --git a/lib/threads.cpp b/lib/threads.cpp index 31fc818b..953ce015 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -207,6 +207,23 @@ int GLVisCommand::PlotCaption(const char *caption) return 0; } +int GLVisCommand::AxisLabels(const char *a_x, const char *a_y, const char *a_z) +{ + if (lock() < 0) + { + return -1; + } + command = AXIS_LABELS; + axis_label_x = a_x; + axis_label_y = a_y; + axis_label_z = a_z; + if (signal() < 0) + { + return -2; + } + return 0; +} + int GLVisCommand::Pause() { if (lock() < 0) @@ -523,6 +540,16 @@ int GLVisCommand::Execute() break; } + case AXIS_LABELS: + { + 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()); + MyExpose(); + break; + } + case PAUSE: { cout << "Command: pause: "; @@ -985,6 +1012,38 @@ void *communication_thread::execute(void *p) goto comm_terminate; } } + else if (_this->ident == "axis_labels") + { + char c; + string label_x, label_y, label_z; + + *_this->is[0] >> ws >> c; // read the opening char + // use the opening char as termination as well + getline(*_this->is[0], label_x, c); + *_this->is[0] >> ws >> c; + getline(*_this->is[0], label_y, c); + *_this->is[0] >> ws >> c; + getline(*_this->is[0], label_z, c); + + // all processors sent the command + for (int i = 1; i < _this->is.Size(); i++) + { + *_this->is[i] >> ws >> _this->ident; // 'axis_label' + *_this->is[i] >> ws >> c; + getline(*_this->is[i], _this->ident, c); + *_this->is[i] >> ws >> c; + getline(*_this->is[i], _this->ident, c); + *_this->is[i] >> ws >> c; + getline(*_this->is[i], _this->ident, c); + } + + if (glvis_command->AxisLabels(label_x.c_str(), + label_y.c_str(), + label_z.c_str())) + { + goto comm_terminate; + } + } else if (_this->ident == "pause") { // all processors sent the command diff --git a/lib/threads.hpp b/lib/threads.hpp index 65dd7799..e2515d9c 100644 --- a/lib/threads.hpp +++ b/lib/threads.hpp @@ -51,7 +51,8 @@ class GLVisCommand CAMERA = 15, AUTOPAUSE = 16, WINDOW_GEOMETRY = 17, - PLOT_CAPTION = 18 + PLOT_CAPTION = 18, + AXIS_LABELS = 19 }; // command to be executed @@ -66,6 +67,9 @@ class GLVisCommand int window_w, window_h; std::string window_title; std::string plot_caption; + std::string axis_label_x; + std::string axis_label_y; + std::string axis_label_z; double view_ang_theta, view_ang_phi; double zoom_factor; int subdiv_tot, subdiv_bdr; @@ -105,6 +109,7 @@ class GLVisCommand int WindowGeometry(int x, int y, int w, int h); int WindowTitle(const char *title); int PlotCaption(const char *caption); + int AxisLabels(const char *a_x, const char *a_y, const char *a_z); int Pause(); int ViewAngles(double theta, double phi); int Zoom(double factor); diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index 16c57d77..5ab0c31a 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -636,29 +636,28 @@ void VisualizationSceneScalarData::DrawCoordinateCross() glListBase (fontbase); #endif - const char *a_labels[] = {"x", "y", "z"}; glRasterPos3d (lenx, 0.0f, 0.0f); - if (print) { gl2psText(a_labels[0],"Times",8); } + if (print) { gl2psText(a_label_x.c_str(),"Times",8); } #ifndef GLVIS_USE_FREETYPE - glCallLists(1, GL_UNSIGNED_BYTE, a_labels[0]); + glCallLists(a_label_x.length(), GL_UNSIGNED_BYTE, a_label_x.c_str()); #else - DrawBitmapText(a_labels[0]); + DrawBitmapText(a_label_x.c_str()); #endif glRasterPos3d (0.0f, leny, 0.0f); - if (print) { gl2psText(a_labels[1],"Times",8); } + if (print) { gl2psText(a_label_y.c_str(),"Times",8); } #ifndef GLVIS_USE_FREETYPE - glCallLists(1, GL_UNSIGNED_BYTE, a_labels[1]); + glCallLists(a_label_y.length(), GL_UNSIGNED_BYTE, a_label_y.c_str()); #else - DrawBitmapText(a_labels[1]); + DrawBitmapText(a_label_y.c_str()); #endif glRasterPos3d (0.0f, 0.0f, lenz); - if (print) { gl2psText(a_labels[2],"Times",8); } + if (print) { gl2psText(a_label_z.c_str(),"Times",8); } #ifndef GLVIS_USE_FREETYPE - glCallLists(1, GL_UNSIGNED_BYTE, a_labels[2]); + glCallLists(a_label_z.length(), GL_UNSIGNED_BYTE, a_label_z.c_str()); #else - DrawBitmapText(a_labels[2]); + DrawBitmapText(a_label_z.c_str()); #endif #ifndef GLVIS_USE_FREETYPE @@ -1182,6 +1181,7 @@ void VisualizationSceneScalarData::SetAutoscale(int _autoscale) VisualizationSceneScalarData::VisualizationSceneScalarData( Mesh & m, Vector & s) + : a_label_x("x"), a_label_y("y"), a_label_z("z") { mesh = &m; sol = &s; @@ -1344,6 +1344,15 @@ void VisualizationSceneScalarData::SetValueRange(double min, double max) UpdateValueRange(true); } +void VisualizationSceneScalarData::SetAxisLabels(const char * a_x, + const char * a_y, + const char * a_z) +{ + a_label_x = a_x; + a_label_y = a_y; + a_label_z = a_z; +} + void VisualizationSceneScalarData::PrepareAxes() { Set_Black_Material(); diff --git a/lib/vsdata.hpp b/lib/vsdata.hpp index 66007e89..a5ed6594 100644 --- a/lib/vsdata.hpp +++ b/lib/vsdata.hpp @@ -57,6 +57,8 @@ class VisualizationSceneScalarData : public VisualizationScene double minv, maxv; + std::string a_label_x, a_label_y, a_label_z; + int scaling, colorbar, drawaxes, axeslist; int auto_ref_max, auto_ref_max_surf_elem; @@ -120,7 +122,8 @@ class VisualizationSceneScalarData : public VisualizationScene /// Shrink factor with respect to the element (material) attributes centers double shrinkmat; - VisualizationSceneScalarData() {} + VisualizationSceneScalarData() + : a_label_x("x"), a_label_y("y"), a_label_z("z") {} VisualizationSceneScalarData (Mesh & m, Vector & s); virtual ~VisualizationSceneScalarData(); @@ -220,6 +223,8 @@ class VisualizationSceneScalarData : public VisualizationScene colorbar = (colorbar ? empty+1 : !empty); } + void SetAxisLabels(const char * a_x, const char * a_y, const char * a_z); + void PrepareAxes(); void ToggleDrawAxes() { diff --git a/lib/vssolution3d.cpp b/lib/vssolution3d.cpp index 55f248a4..dee3ea5a 100644 --- a/lib/vssolution3d.cpp +++ b/lib/vssolution3d.cpp @@ -1783,7 +1783,7 @@ void VisualizationSceneSolution3d::PrepareLines() void VisualizationSceneSolution3d::PrepareLines2() { - int i, j, k, fn, fo, di; + int i, j, k, fn, fo, di = 0; double bbox_diam; glNewList (linelist, GL_COMPILE); diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index aad02db1..8130f039 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -564,7 +564,7 @@ void VisualizationSceneVector3d::PrepareFlat() void VisualizationSceneVector3d::PrepareFlat2() { - int i, k, fn, fo, di, have_normals; + int i, k, fn, fo, di = 0, have_normals; double bbox_diam, vmin, vmax; int dim = mesh->Dimension(); int ne = (dim == 3) ? mesh->GetNBE() : mesh->GetNE(); @@ -929,7 +929,7 @@ void VisualizationSceneVector3d::PrepareLines() void VisualizationSceneVector3d::PrepareLines2() { - int i, j, k, fn, fo, di; + int i, j, k, fn, fo, di = 0; double bbox_diam; glNewList (linelist, GL_COMPILE);