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).

Square

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");
}