Add direct cutting-plane control to GLVis scripts#374
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new cutting_plane GLVis script command to set cutting-plane orientation, translation, kind, and algorithm directly in one call, avoiding the expensive step-by-step recomputation caused by replaying multiple keystrokes.
Changes:
- Introduces
Plane::SetPlane()to set cutting-plane orientation/position directly. - Adds a virtual
VisualizationSceneScalarData::SetCuttingPlane()hook and implements it forVisualizationSceneSolution3d. - Registers and parses a new
cutting_planecommand in the script controller (degrees in scripts, converted to radians internally).
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/vssolution3d.hpp | Declares VisualizationSceneSolution3d::SetCuttingPlane(...) override. |
| lib/vssolution3d.cpp | Implements SetCuttingPlane(...) to update plane, kind, algorithm, and trigger recomputation. |
| lib/vsdata.hpp | Adds Plane::SetPlane(...) and a default no-op SetCuttingPlane(...) hook in the base scene class. |
| lib/vsdata.cpp | Implements Plane::SetPlane(...) using stored bounding-box center + translation along the plane normal. |
| lib/script_controller.cpp | Adds the cutting_plane script command, parses optional args, and calls vs->SetCuttingPlane(...). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
Btw, do not mind the failing CI on mac, it is happening on master as well (https://github.com/GLVis/glvis/actions/runs/29534330078/job/87741910839) 🫣 . |
|
@najlkin or @camierjs , I am not familiar enough with the GLVis flow control to resolve this copilot comment. Could you please help with this? |
| // 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". |
There was a problem hiding this comment.
Please use doxygen style. We do not publish it anymore on the webpage, but you can still build it locally.
| virtual void SetCuttingPlane(double phi, double theta, double translation, | ||
| int kind, int algo) { } |
There was a problem hiding this comment.
| virtual void SetCuttingPlane(double phi, double theta, double translation, | |
| int kind, int algo) { } | |
| virtual void SetCuttingPlane(double phi, double theta, double translation, | |
| int kind = -1, int algo = -1) { } |
| void SetCuttingPlane(double phi, double theta, double translation, | ||
| int kind, int algo) override; |
There was a problem hiding this comment.
| void SetCuttingPlane(double phi, double theta, double translation, | |
| int kind, int algo) override; | |
| void SetCuttingPlane(double phi, double theta, double translation, | |
| int kind = -1, int algo = -1) override; |
| << " (expected -1..2)" << endl; | ||
| kind = 1; | ||
| } | ||
| if (algo != -1 && (algo < 0 || algo > 1)) |
There was a problem hiding this comment.
| if (algo != -1 && (algo < 0 || algo > 1)) | |
| if (algo < -1 || algo > 1) |
| if (algo != -1 && (algo < 0 || algo > 1)) | ||
| { | ||
| cerr << "Script: cutting_plane: invalid alg " << algo | ||
| << " (expected 0 or 1)" << endl; |
There was a problem hiding this comment.
Fix this message please to include -1.
| (*this)[Command::PlotCaption] = {"plot_caption", "'<caption>'", "Set the plot caption."}; | ||
| (*this)[Command::PointLine] = {"pointline", "<num_points> <x y z>...", "Set point line overlay coordinates."}; | ||
| (*this)[Command::Headless] = {"headless", "", "Change the session to headless."}; | ||
| (*this)[Command::CuttingPlane] = {"cutting_plane", "<phi> <theta> <translation> <kind:optional, default 1> <alg:optional>", "Set the cutting plane orientation (degrees), translation, kind, and algorithm."}; |
There was a problem hiding this comment.
| (*this)[Command::CuttingPlane] = {"cutting_plane", "<phi> <theta> <translation> <kind:optional, default 1> <alg:optional>", "Set the cutting plane orientation (degrees), translation, kind, and algorithm."}; | |
| (*this)[Command::CuttingPlane] = {"cutting_plane", "<phi> <theta> <translation> [<kind> [<alg>]]", "Set the cutting plane orientation (degrees), translation, kind (default: 1), and algorithm."}; |
Motivation
Today, the only way to position the 3D cutting plane from a GLVis script is to replay raw keystrokes via keys. Even a modest plane orientation requires several keystrokes:
(5
xpresses to rotatephiby 25°, 8ypresses to rotatethetaby 40°, thenito enable the plane). Each individual keystroke triggers a full cutting-plane geometry recomputation, not just the final one. On a large mesh that's a lot of wasted computation just to reach a state that could be stated directly in one line.What this adds
A single script command:
which sets the plane's orientation (degrees), translation, kind (cut-through-elements / solid-cut-behind / off), and algorithm (accurate / fast) directly, in one shot reproducing exactly what the equivalent keystroke sequence would have produced, without the redundant intermediate recomputations.
kinddefaults to 1 (cut through elements) so the plane is visible immediately;algis optional and leaves the current value unchanged when omitted.Implementation
Plane::SetPlane: new direct setter on the existingPlaneclass (previously only relativeIncrease/Decreasemutators existed).VisualizationSceneScalarData::SetCuttingPlane: empty-default virtual hook (2D scenes no-op safely).VisualizationSceneSolution3d::SetCuttingPlane— override combining plane move + kind + algorithm changes, mirroring the existing key-handler logic.cutting_planeregistered in the script command table.