Skip to content
/ SMesh Public

A polygon mesh manipulation library based on the Surface Mesh structure

License

Notifications You must be signed in to change notification settings

Bendzae/SMesh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

127 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CI crates.io

SMesh

Caution

Library is still work in progress

SMesh is a polygon mesh manipulation library based on the Surface Mesh data structure and the pmp library and the halfedge-mesh implementation of the blackjack project.

Version Compatibility

SMesh Version Bevy Version
0.2.7 0.17
0.2.5 0.16

The goal of this library is to provide a flexible mesh abstraction and set of operations to be used for procedural modeling and procedural generation of 3D meshes.

Examples

tree_example parameterized procedural mesh generation

cargo run --example tree

extrude_example mesh extrusion and manipulation example with the visual debug tools enabled

cargo run --example extrude

UV Unwrapping Example

Interactive example demonstrating all UV unwrapping methods on four different primitives with a checkerboard texture:

cargo run --example uv_unwrap --features xatlas

Press SPACE to cycle through UV methods: Planar Z, Planar Y, Cylindrical Y, Spherical, Cube, and XAtlas Auto. The four primitives (Cube, Sphere, Cylinder, and a complex extruded shape) update simultaneously to show how each method performs on different geometry.

Usage

Preface: Mesh elements in SMesh are identified by a unique typesafe id, which can be of type: VertexId, HalfedgeId and FaceId.

Mesh creation

SMesh has a simple api to add vertices to your mesh and connect them to faces: Add vertices

    let mut smesh = SMesh::new();
    let v0 = smesh.add_vertex(vec3(-1.0, -1.0, 0.0)); // Returns a unique VertexId
    let v1 = smesh.add_vertex(vec3(1.0, -1.0, 0.0));
    let v2 = smesh.add_vertex(vec3(1.0, 1.0, 0.0));
    let v3 = smesh.add_vertex(vec3(-1.0, 1.0, 0.0));

Build face

    smesh.add_face(vec![v0, v1, v2, v3])?;

Mesh queries

SMesh provides a chainable api to query mesh elements using the typical halfedge-mesh relationships:

get outgoing halfedge of a vertex

let outgoing_halfedge_query = v0.halfedge(); // returns a MeshQueryBuilder<HalfedgeId>

you can execute the query on a smesh instance by using .run(&smesh)

let outgoing_halfedge = v0.halfedge().run(&smesh)?;  // returns a HalfedgeId

chaining queries

let vertex = v0.halfedge_to(v1).cw_rotated_neighbour().dst_vert().run(&smesh)?;  // returns a VertexId

Mesh operations

SMesh provides a comprehensive set of mesh manipulation operations:

Topological Operations

// Insert a vertex along an edge
let new_halfedge = mesh.insert_vertex(halfedge_id, vertex_id)?;

// Delete mesh elements
mesh.delete_vertex(vertex_id)?;
mesh.delete_edge(halfedge_id)?;
mesh.delete_face(face_id)?;

// Edge collapse (for triangle meshes)
if mesh.is_collapse_ok(halfedge_id).is_ok() {
    mesh.collapse(halfedge_id)?;
}

// Remove edge (merges adjacent faces)
if mesh.is_removal_ok(halfedge_id).is_ok() {
    mesh.remove_edge(halfedge_id)?;
}

Edit Operations

// Extrude a single face
let new_face = mesh.extrude(face_id)?;

// Extrude multiple faces
let new_faces = mesh.extrude_faces(vec![face1, face2, face3])?;

// Extrude a boundary edge
let new_edge = mesh.extrude_edge(halfedge_id)?;

// Extrude a chain of connected boundary edges
let new_edges = mesh.extrude_edge_chain(vec![edge1, edge2, edge3])?;

// Subdivide faces
let selection = MeshSelection::from(vec![face1, face2]);
let new_selection = mesh.subdivide(selection)?;

// Combine two meshes
mesh.combine_with(other_mesh)?;

Transform Operations

All transform operations work with selections (vertices, edges, or faces):

use smesh::smesh::transform::Pivot;

// Translate
mesh.translate(face_id, Vec3::new(0.0, 1.0, 0.0))?;

// Scale around a pivot point
mesh.scale(
    vec![face1, face2],
    Vec3::new(2.0, 2.0, 2.0),
    Pivot::SelectionCog
)?;

// Rotate using a quaternion
mesh.rotate(
    vertex_id,
    Quat::from_rotation_y(PI / 4.0),
    Pivot::Origin
)?;

// Set position relative to a pivot
mesh.set_position(selection, Vec3::new(5.0, 0.0, 0.0), Pivot::MeshCog)?;

Available pivot options: Pivot::Origin, Pivot::MeshCog, Pivot::SelectionCog, Pivot::Point(Vec3)

Primitives

SMesh includes built-in primitive generators:

use smesh::smesh::primitives::*;

// Create a cube with subdivisions
let (cube, data) = Cube {
    subdivision: U16Vec3::new(2, 2, 2)
}.generate()?;

// Create an icosphere
let (sphere, data) = Icosphere {
    subdivisions: 3
}.generate()?;

// Create a cylinder
let (cylinder, data) = Cylinder {
    segments: 16,
    height: 2.0,
    radius: 0.5
}.generate()?;

// Create other primitives
let (quad, data) = Quad.generate()?;
let (circle, data) = Circle { segments: 32 }.generate()?;

Please check the examples for more :)

UV Unwrapping

SMesh supports both simple projection-based UV mapping and automatic UV unwrapping via xatlas.

Simple Projection Methods (built-in, no features required):

use smesh::smesh::uv_operations::ProjectionAxis;

// Planar projection
mesh.planar_project_uvs(ProjectionAxis::Z)?;

// Cylindrical projection
mesh.cylindrical_project_uvs(ProjectionAxis::Y)?;

// Spherical projection
mesh.spherical_project_uvs(Vec3::ZERO)?;

// Cube projection
mesh.cube_project_uvs(Vec3::ZERO)?;

Automatic UV Unwrapping via xatlas (requires xatlas feature):

[dependencies]
smesh = { version = "0.2", features = ["xatlas"] }

Then generate UVs for your mesh:

// Simple automatic unwrapping
mesh.auto_uv_unwrap()?;

// With custom options
use smesh::smesh::xatlas_integration::XatlasOptions;

let options = XatlasOptions::default();
mesh.auto_uv_unwrap_with_options(options)?;

Goals

I aim to provide a flexible rust implementation of the Surface Mesh with a focus on usefulness for procedural mesh generation. Other goals are:

  • Ergonomic and easy-to-use api
  • Port most operations from the pmp library and blackjack
  • Support most operations that are possible in modern 3D modeling software like blender
  • Integration with the bevy game engine
  • Target manifold tri & quad meshes for now

About

A polygon mesh manipulation library based on the Surface Mesh structure

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •