Module utils

Source
Expand description

Low-level utilities for mesh and geometry generation.

This module provides primitive building blocks for constructing triangle meshes and other geometric structures. These functions are primarily used internally by Parry’s shape-to-mesh conversion utilities, but are exposed for users who need fine-grained control over mesh generation.

§Overview

The utilities fall into several categories:

§Point Transformations

§Vertex Generation

  • push_circle - Generate circle points in 3D (XZ plane)
  • push_arc - Generate arc points between two endpoints

§Index Buffer Generation

  • push_ring_indices / push_open_ring_indices - Connect two circles into a tube
  • push_rectangle_indices - Generate two triangles forming a quad
  • push_degenerate_top_ring_indices - Connect circle to a single apex point
  • push_filled_circle_indices - Fill a circle with triangles (fan triangulation)

§Edge/Outline Generation

  • push_circle_outline_indices - Edge loop for a closed circle
  • push_open_circle_outline_indices - Edge chain (not closed)
  • push_arc_idx - Edge indices for an arc

§Advanced Operations

  • reverse_clockwising - Flip triangle winding order (reverse normals)
  • apply_revolution - Create surface of revolution from a profile curve
  • push_arc_and_idx - Generate arc geometry and indices together

§Usage Patterns

§Building a Cylinder

use parry3d::transformation::utils::{push_circle, push_ring_indices, push_filled_circle_indices};
use parry3d::math::Point;
use std::f32::consts::PI;

let mut vertices = Vec::new();
let mut indices = Vec::new();

let radius = 2.0;
let height = 10.0;
let nsubdiv = 16;
let dtheta = 2.0 * PI / nsubdiv as f32;

// Create bottom and top circles
push_circle(radius, nsubdiv, dtheta, 0.0, &mut vertices);      // Bottom at y=0
push_circle(radius, nsubdiv, dtheta, height, &mut vertices);   // Top at y=height

// Connect the circles to form the cylinder body
push_ring_indices(0, nsubdiv, nsubdiv, &mut indices);

// Cap the bottom
push_filled_circle_indices(0, nsubdiv, &mut indices);

// Cap the top
push_filled_circle_indices(nsubdiv, nsubdiv, &mut indices);

println!("Cylinder: {} vertices, {} triangles", vertices.len(), indices.len());

§Building a Cone

use parry3d::transformation::utils::{push_circle, push_degenerate_top_ring_indices, push_filled_circle_indices};
use parry3d::math::Point;
use std::f32::consts::PI;

let mut vertices = Vec::new();
let mut indices = Vec::new();

let radius = 3.0;
let height = 5.0;
let nsubdiv = 20;
let dtheta = 2.0 * PI / nsubdiv as f32;

// Create the base circle
push_circle(radius, nsubdiv, dtheta, 0.0, &mut vertices);

// Add apex point at the top
vertices.push(Point::new(0.0, height, 0.0));
let apex_idx = (vertices.len() - 1) as u32;

// Connect base circle to apex
push_degenerate_top_ring_indices(0, apex_idx, nsubdiv, &mut indices);

// Cap the base
push_filled_circle_indices(0, nsubdiv, &mut indices);

println!("Cone: {} vertices, {} triangles", vertices.len(), indices.len());

§Transforming Existing Geometry

use parry3d::transformation::utils::{transform, scaled};
use parry3d::math::{Point, Vector, Isometry};
use parry3d::na::{Translation3, UnitQuaternion};
use std::f32::consts::PI;

let mut points = vec![
    Point::new(1.0, 0.0, 0.0),
    Point::new(0.0, 1.0, 0.0),
    Point::new(0.0, 0.0, 1.0),
];

// First, scale non-uniformly
let points = scaled(points, Vector::new(2.0, 1.0, 0.5));

// Then rotate 45 degrees around Y axis
let rotation = UnitQuaternion::from_axis_angle(&Vector::y_axis(), PI / 4.0);
let translation = Translation3::new(10.0, 5.0, 0.0);
let isometry = Isometry::from_parts(translation.into(), rotation);

let final_points = parry3d::transformation::utils::transformed(points, isometry);

§Design Philosophy

These functions follow a “builder” pattern where:

  1. Vertices are pushed to a Vec<Point<Real>>
  2. Indices are pushed to a Vec<[u32; 3]> (triangles) or Vec<[u32; 2]> (edges)
  3. Functions work with index offsets, allowing incremental construction
  4. No memory is allocated except for the output buffers

This design allows for efficient, flexible mesh construction with minimal overhead.

§Performance Notes

  • All functions use simple loops without SIMD (suitable for small to medium subdivisions)
  • Index generation has O(n) complexity where n is the subdivision count
  • Point generation involves trigonometric functions (sin/cos) per subdivision
  • For high subdivision counts (>1000), consider caching generated geometry

§See Also

  • to_trimesh module - High-level shape to mesh conversion (see individual shape to_trimesh() methods)
  • convex_hull - Convex hull computation
  • TriMesh - Triangle mesh shape

Functions§

apply_revolution
Applies a revolution, using the Y symmetry axis passing through the origin.
push_arc
Pushes points forming an arc between two points around a center.
push_arc_and_idx
Pushes to out_vtx a set of points forming an arc starting at start, ending at end with revolution center at center. The curve is approximated by pushing nsubdivs points. The start and end point are not pushed to out_vtx.
push_arc_idx
Pushes the index buffer for an arc between start and end and intermediate points in the range arc.
push_circle
Pushes a discretized counterclockwise circle to a buffer.
push_circle_outline_indices
Pushes the index buffer of a closed loop.
push_degenerate_open_top_ring_indices
Creates the faces from a circle and a point that is shared by all triangle.
push_degenerate_top_ring_indices
Creates the faces from a circle and a point that is shared by all triangle.
push_filled_circle_indices
Pushes indices so that a circle is filled with triangles. Each triangle will have the base_circle point in common. Pushes nsubdiv - 2 elements to out.
push_open_circle_outline_indices
Pushes the index buffer of an open chain.
push_open_ring_indices
Creates the triangle faces connecting two circles, leaving the ring open.
push_rectangle_indices
Pushes two triangles forming a rectangle to the index buffer.
push_ring_indices
Creates the triangle faces connecting two circles with the same discretization.
reverse_clockwising
Reverses the winding order of triangle faces.
scaled
Returns the scaled version of a vector of points.
transform
Applies in-place a transformation to an array of points.
transformed
Returns the transformed version of a vector of points.