Plot3D Rust version
Rust utilities for reading, writing, and analysing NASA PLOT3D structured grids. The crate draws heavily on the excellent plot3d Python project maintained by NASA. If you are looking for a battle-tested Python implementation with a rich set of examples, start there. This repository is a Rust reimagining that keeps the same data model while taking advantage of Rust’s type safety, performance, and interoperability.
Features
- Parse ASCII and binary PLOT3D files into strongly typed
Blockstructures - Compute face connectivity, including periodic interfaces and exterior surfaces
- Reduce meshes via common divisors to accelerate matching operations
- Rotate blocks with arbitrary axes and angles and detect rotational periodicity
- Export meshes back to PLOT3D formats
- Utilities for translational periodicity, block merging, and lightweight graph analyses
Many algorithms mirror the behaviour of the Python utilities one-for-one, making it straightforward to port workflows between languages or compare outputs across implementations.
Installation
Add the crate to your Cargo.toml:
[]
= "0.1"
Can also do add by running cargo add plot3d
The crate uses the 2021 edition of Rust and depends on common ecosystem crates such as serde, ndarray, and reqwest for optional test helpers.
Quick Start
use ;
For rotational periodicity detection:
use ;
Orientation & Permutation Matrices
When two block faces share an interface, their parametric (u, v) coordinate
systems may differ by any combination of axis reversal and transposition. The
crate encodes all 8 possible orientations as a 3-bit index into the
PERMUTATION_MATRICES constant array of 2x2 matrices.
Bit encoding
The permutation_index stored in [Orientation] is built from three boolean
flags:
permutation_index = u_reversed | (v_reversed << 1) | (swapped << 2)
| Index | Binary | u_reversed | v_reversed | swapped | Matrix | Effect |
|---|---|---|---|---|---|---|
| 0 | 000 |
no | no | no | [[ 1, 0],[ 0, 1]] |
identity |
| 1 | 001 |
yes | no | no | [[-1, 0],[ 0, 1]] |
flip u |
| 2 | 010 |
no | yes | no | [[ 1, 0],[ 0,-1]] |
flip v |
| 3 | 011 |
yes | yes | no | [[-1, 0],[ 0,-1]] |
flip both |
| 4 | 100 |
no | no | yes | [[ 0, 1],[ 1, 0]] |
transpose |
| 5 | 101 |
yes | no | yes | [[ 0,-1],[ 1, 0]] |
transpose + flip u |
| 6 | 110 |
no | yes | yes | [[ 0, 1],[-1, 0]] |
transpose + flip v |
| 7 | 111 |
yes | yes | yes | [[ 0,-1],[-1, 0]] |
transpose + both |
Why 8 permutations?
In-plane matches (both faces share the same constant axis, e.g. both K-constant) can usually be described by simply reversing one or both diagonal corners. Cross-plane matches (e.g. a K-constant face abutting a J-constant face) additionally require a swap of the u and v axes, giving the full set of 8 orientations.
Accessing orientation from a FaceMatch
After running connectivity_fast, each FaceMatch carries an optional
orientation field:
use ;
let blocks = read_plot3d_ascii.unwrap;
let = connectivity_fast;
for m in &matches
The Orientation struct also provides convenience accessors:
u_reversed(), v_reversed(), swapped(), and matrix().
Relationship to the Python Project
The original Python implementation includes comprehensive notebooks, example data, and a GUI. plot3d-rs strives to remain API-compatible where possible:
- File I/O routines mirror the signatures of
plot3d.read_plot3Dand friends - Connectivity pipelines (
connectivity,connectivity_fast, periodicity detection) follow the same logic and produce comparable results - Many structs (e.g.,
FaceRecord,FaceMatch,PeriodicPair) are direct translations of the Python dictionaries used in the NASA project
When uncertain about the expected behaviour, use the Python utilities as ground truth. The Rust crate is intentionally lightweight and pragmatic, making it well-suited for embedding PLOT3D workflows in larger Rust applications or integrating with other numerical codes.
Documentation
- Unverified Connectivity Faces: Root Cause Analysis — why cross-plane face connections need orientation flags beyond lb/ub, and how plot3d-rs handles them
- Presentation (PowerPoint) — visual walkthrough of the 2D→3D combinatorics and the orientation fix
Contributing
Bug reports, feature suggestions, and pull requests are welcome. If you find a discrepancy between this crate and the Python reference, please open an issue referencing the relevant Python behaviour so we can keep the implementations aligned.
License
This project is licensed under the MIT license.