From 3dc9c7de96a4420e8adad362b8713be627769582 Mon Sep 17 00:00:00 2001 From: arotem3 Date: Thu, 16 Jul 2026 15:59:07 -0400 Subject: [PATCH 1/5] added cutting_plane script command --- lib/script_controller.cpp | 33 +++++++++++++++++++++++++++++++++ lib/vsdata.cpp | 17 +++++++++++++++++ lib/vsdata.hpp | 8 ++++++++ lib/vssolution3d.cpp | 30 ++++++++++++++++++++++++++++++ lib/vssolution3d.hpp | 2 ++ 5 files changed, 90 insertions(+) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index e283ac53..97a38f12 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include using namespace std; using namespace mfem; @@ -63,6 +65,7 @@ enum class Command PlotCaption, PointLine, Headless, + CuttingPlane, //---------- Max }; @@ -128,6 +131,7 @@ ScriptCommands::ScriptCommands() (*this)[Command::PlotCaption] = {"plot_caption", "''", "Set the plot caption."}; (*this)[Command::PointLine] = {"pointline", " ...", "Set point line overlay coordinates."}; (*this)[Command::Headless] = {"headless", "", "Change the session to headless."}; + (*this)[Command::CuttingPlane] = {"cutting_plane", " ", "Set the cutting plane orientation (degrees), translation, kind, and algorithm."}; } int ScriptController::ScriptReadSolution(istream &scr, DataState &state) @@ -859,6 +863,35 @@ bool ScriptController::ExecuteScriptCommand() case Command::Headless: cout << "The session cannot become headless after initialization" << endl; break; + case Command::CuttingPlane: + { + double phi_deg, theta_deg, translation; + scr >> phi_deg >> theta_deg >> translation; + + int kind = -1, algo = -1; + scr >> ws; + if (isdigit((unsigned char)scr.peek()) || scr.peek() == '-') + { + scr >> kind; + scr >> ws; + if (isdigit((unsigned char)scr.peek()) || scr.peek() == '-') + { + scr >> algo; + } + } + + cout << "Script: cutting_plane: " << phi_deg << ' ' << theta_deg + << ' ' << translation; + if (kind != -1) { cout << ' ' << kind; } + if (algo != -1) { cout << ' ' << algo; } + cout << endl; + + win.vs->SetCuttingPlane(phi_deg * M_PI / 180.0, + theta_deg * M_PI / 180.0, + translation, kind, algo); + MyExpose(); + } + break; case Command::Max: //dummy break; } diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index 5853e7b7..31ef8137 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -1986,6 +1986,7 @@ Plane::Plane(const double (&eqn_)[4], const VisualizationScene::Box &bb) x0 = (x[0]+x[1])/2.0; y0 = (y[0]+y[1])/2.0; z0 = (z[0]+z[1])/2.0; + cx = x0; cy = y0; cz = z0; phi_step = M_PI / 36; theta_step = M_PI / 36; @@ -2050,3 +2051,19 @@ void Plane::DecreaseDistance() eqn[3] -= rho_step; CartesianToSpherical(); } + +void Plane::SetPlane(double phi_, double theta_, double translation) +{ + phi = phi_; + theta = theta_; + rho = 1.0; + + double nx = cos(phi) * cos(theta); + double ny = cos(phi) * sin(theta); + double nz = sin(phi); + x0 = cx + translation * nx; + y0 = cy + translation * ny; + z0 = cz + translation * nz; + + SphericalToCartesian(); +} diff --git a/lib/vsdata.hpp b/lib/vsdata.hpp index d844cb0a..7af0be6c 100644 --- a/lib/vsdata.hpp +++ b/lib/vsdata.hpp @@ -23,6 +23,7 @@ class Plane double eqn[4]; double phi, theta, rho; double x0,y0,z0; + double cx, cy, cz; // fixed mesh bounding-box center void CartesianToSpherical(); void SphericalToCartesian(); @@ -44,6 +45,7 @@ class Plane void DecreaseTheta(); void IncreaseDistance(); void DecreaseDistance(); + void SetPlane(double phi_, double theta_, double translation); }; @@ -263,6 +265,12 @@ class VisualizationSceneScalarData : public VisualizationScene virtual void AutoRefine() = 0; virtual void ToggleAttributes(mfem::Array &attr_list) = 0; + // Set the cutting-plane orientation (radians), translation, kind, and + // algorithm in one shot. No-op by default; only meaningful for 3D scenes. + // kind == -1 / algo == -1 mean "leave unchanged". + virtual void SetCuttingPlane(double phi, double theta, double translation, + int kind, int algo) { } + virtual void PrintState(); mfem::Mesh *GetMesh() { return mesh; } diff --git a/lib/vssolution3d.cpp b/lib/vssolution3d.cpp index 0173c033..f363c51d 100644 --- a/lib/vssolution3d.cpp +++ b/lib/vssolution3d.cpp @@ -1192,6 +1192,36 @@ void VisualizationSceneSolution3d::ToggleCPAlgorithm() } } +void VisualizationSceneSolution3d::SetCuttingPlane(double phi, double theta, + double translation, + int kind, int algo) +{ + CuttingPlane->SetPlane(phi, theta, translation); + FindNodePos(); + + if (kind != -1 && kind != cplane) + { + if (cplane == 2 && cp_drawmesh == 3) + { + cp_drawmesh = 2; + } + cplane = kind; + } + + if (algo != -1) + { + cp_algo = algo; + } + + CPPrepare(); + if (cplane == 0 || cplane == 2) + { + Prepare(); + PrepareLines(); + PrepareOrderingCurve(); + } +} + void VisualizationSceneSolution3d::MoveLevelSurf(int move) { drawlsurf += move; diff --git a/lib/vssolution3d.hpp b/lib/vssolution3d.hpp index 49d0d5dd..ed4ae4c0 100644 --- a/lib/vssolution3d.hpp +++ b/lib/vssolution3d.hpp @@ -218,6 +218,8 @@ class VisualizationSceneSolution3d : public VisualizationSceneScalarData void ToggleCPDrawElems(); void ToggleCPDrawMesh(); void ToggleCPAlgorithm(); + void SetCuttingPlane(double phi, double theta, double translation, + int kind, int algo) override; void MoveLevelSurf(int); void NumberOfLevelSurf(int); void EventUpdateColors() override; From d757215c4da7b51bfebf1202732957cc79e786ba Mon Sep 17 00:00:00 2001 From: arotem3 Date: Thu, 16 Jul 2026 16:22:56 -0400 Subject: [PATCH 2/5] updated default behavior of cutting plane --- lib/script_controller.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index 97a38f12..36d4a013 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -131,7 +131,7 @@ ScriptCommands::ScriptCommands() (*this)[Command::PlotCaption] = {"plot_caption", "''", "Set the plot caption."}; (*this)[Command::PointLine] = {"pointline", " ...", "Set point line overlay coordinates."}; (*this)[Command::Headless] = {"headless", "", "Change the session to headless."}; - (*this)[Command::CuttingPlane] = {"cutting_plane", " ", "Set the cutting plane orientation (degrees), translation, kind, and algorithm."}; + (*this)[Command::CuttingPlane] = {"cutting_plane", " ", "Set the cutting plane orientation (degrees), translation, kind, and algorithm."}; } int ScriptController::ScriptReadSolution(istream &scr, DataState &state) @@ -868,7 +868,7 @@ bool ScriptController::ExecuteScriptCommand() double phi_deg, theta_deg, translation; scr >> phi_deg >> theta_deg >> translation; - int kind = -1, algo = -1; + int kind = 1, algo = -1; scr >> ws; if (isdigit((unsigned char)scr.peek()) || scr.peek() == '-') { @@ -881,8 +881,7 @@ bool ScriptController::ExecuteScriptCommand() } cout << "Script: cutting_plane: " << phi_deg << ' ' << theta_deg - << ' ' << translation; - if (kind != -1) { cout << ' ' << kind; } + << ' ' << translation << ' ' << kind; if (algo != -1) { cout << ' ' << algo; } cout << endl; From 1c421902f8dc478d6f87742a283929391729744b Mon Sep 17 00:00:00 2001 From: Amit Rotem <40644295+arotem3@users.noreply.github.com> Date: Thu, 16 Jul 2026 17:18:25 -0400 Subject: [PATCH 3/5] Add range checks for script input Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- lib/script_controller.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index 36d4a013..91b9ed82 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -870,16 +870,31 @@ bool ScriptController::ExecuteScriptCommand() int kind = 1, algo = -1; scr >> ws; - if (isdigit((unsigned char)scr.peek()) || scr.peek() == '-') + int ch = scr.peek(); + if (ch != std::char_traits::eof() && (isdigit(ch) || ch == '-')) { scr >> kind; scr >> ws; - if (isdigit((unsigned char)scr.peek()) || scr.peek() == '-') + ch = scr.peek(); + if (ch != std::char_traits::eof() && (isdigit(ch) || ch == '-')) { scr >> algo; } } + if (kind < -1 || kind > 2) + { + cerr << "Script: cutting_plane: invalid kind " << kind + << " (expected -1..2)" << endl; + kind = 1; + } + if (algo != -1 && (algo < 0 || algo > 1)) + { + cerr << "Script: cutting_plane: invalid alg " << algo + << " (expected 0 or 1)" << endl; + algo = -1; + } + cout << "Script: cutting_plane: " << phi_deg << ' ' << theta_deg << ' ' << translation << ' ' << kind; if (algo != -1) { cout << ' ' << algo; } From 4a22f38b29804ccc8c7da590e7b5417a9b732c9b Mon Sep 17 00:00:00 2001 From: arotem3 Date: Sat, 18 Jul 2026 11:55:49 -0400 Subject: [PATCH 4/5] removed EOF from char check --- lib/script_controller.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/script_controller.cpp b/lib/script_controller.cpp index 91b9ed82..fae7c257 100644 --- a/lib/script_controller.cpp +++ b/lib/script_controller.cpp @@ -871,12 +871,12 @@ bool ScriptController::ExecuteScriptCommand() int kind = 1, algo = -1; scr >> ws; int ch = scr.peek(); - if (ch != std::char_traits::eof() && (isdigit(ch) || ch == '-')) + if (isdigit(ch) || ch == '-') { scr >> kind; scr >> ws; ch = scr.peek(); - if (ch != std::char_traits::eof() && (isdigit(ch) || ch == '-')) + if (isdigit(ch) || ch == '-') { scr >> algo; } From cc8b16ae6a657453f530860ac8555d1505ef65bb Mon Sep 17 00:00:00 2001 From: arotem3 Date: Sat, 18 Jul 2026 12:09:51 -0400 Subject: [PATCH 5/5] added conditional check for preparation when setting cutting plane --- lib/vssolution3d.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/vssolution3d.cpp b/lib/vssolution3d.cpp index f363c51d..b5f2afe9 100644 --- a/lib/vssolution3d.cpp +++ b/lib/vssolution3d.cpp @@ -1196,6 +1196,8 @@ void VisualizationSceneSolution3d::SetCuttingPlane(double phi, double theta, double translation, int kind, int algo) { + const int old_cplane = cplane; + CuttingPlane->SetPlane(phi, theta, translation); FindNodePos(); @@ -1214,11 +1216,15 @@ void VisualizationSceneSolution3d::SetCuttingPlane(double phi, double theta, } CPPrepare(); - if (cplane == 0 || cplane == 2) + if (old_cplane == 2 || cplane == 2) { Prepare(); PrepareLines(); - PrepareOrderingCurve(); + + if (cplane != old_cplane) + { + PrepareOrderingCurve(); + } } }