Square
Keep working in the same truck_meshes library so shapes can import each other, and place each shape in its own file.
Reference code: same setup as triangle, but with 4 vertices.
Add the square module
src/lib.rs additions:
#![allow(unused)] fn main() { use truck_meshalgo::prelude::*; // ...keep `write_polygon_mesh` and `triangle()` above... pub mod square; // add this pub use square::square; // add this }
Construct Main Function
src/square.rs:
#![allow(unused)] fn main() { use std::iter::FromIterator; use truck_meshalgo::prelude::*; /// A unit square in the XY plane made from two triangles. pub fn square() -> PolygonMesh { //PLACE STEP 1-4 HERE } }
Step 1: Define vertex positions
#![allow(unused)] fn main() { let positions = vec![ Point3::new(0.0, 0.0, 0.0), // bottom-left [0] Point3::new(1.0, 0.0, 0.0), // bottom-right [1] Point3::new(1.0, 1.0, 0.0), // top-right [2] Point3::new(0.0, 1.0, 0.0), // top-left [3] ]; }
Step 2: Build attribute set
#![allow(unused)] fn main() { let attrs = StandardAttributes { positions, ..Default::default() }; }
Step 3: Define mesh faces
#![allow(unused)] fn main() { let faces = Faces::from_iter([ [0, 1, 2], // bottom-right triangle [0, 2, 3], // top-left triangle ]); }
Prefer a single quad? Swap the faces line in Step 3 for:
#![allow(unused)] fn main() { let faces = Faces::from_iter([[0, 1, 2, 3]]); }
Step 4: Construct the mesh
#![allow(unused)] fn main() { PolygonMesh::new(attrs, faces) }
Export the square
Add examples/square.rs:
fn main() { let mesh = truck_meshes::square(); truck_meshes::write_polygon_mesh(&mesh, "output/square.obj"); }
Run it:
cargo run --example square
View it
Open output/square.obj in Preview/3D Viewer/ParaView/Blender. You should see a single square.
Image below from Preview (mac).

File tree after this step
truck_meshes/
├─ Cargo.toml
├─ src/
│ ├─ lib.rs
│ ├─ triangle.rs
│ └─ square.rs
├─ examples/
│ ├─ triangle.rs
│ └─ square.rs
└─ output/ # exported OBJ files (e.g., output/square.obj)
Full code:
src/lib.rs:
#![allow(unused)] fn main() { use truck_meshalgo::prelude::*; /// Write any mesh to an OBJ file. pub fn write_polygon_mesh(mesh: &PolygonMesh, path: &str) { let mut obj = std::fs::File::create(path).unwrap(); obj::write(mesh, &mut obj).unwrap(); } pub mod triangle; pub use triangle::triangle; pub mod square; pub use square::square; }
src/square.rs:
#![allow(unused)] fn main() { use std::iter::FromIterator; use truck_meshalgo::prelude::*; pub fn square() -> PolygonMesh { let positions = vec![ Point3::new(0.0, 0.0, 0.0), Point3::new(1.0, 0.0, 0.0), Point3::new(1.0, 1.0, 0.0), Point3::new(0.0, 1.0, 0.0), ]; let attrs = StandardAttributes { positions, ..Default::default() }; let faces = Faces::from_iter([ [0, 1, 2], [0, 2, 3], ]); PolygonMesh::new(attrs, faces) } }
examples/square.rs:
fn main() { let mesh = truck_meshes::square(); truck_meshes::write_polygon_mesh(&mesh, "output/square.obj"); }