Skip to main content

Mesh

Struct Mesh 

Source
pub struct Mesh { /* private fields */ }
Expand description

An editable triangle mesh stored in slots.

Vertices and triangles are addressed by slot ids that stay stable across edits, undo and redo. Removed slots are dead: positions() and triangles() still contain them (removed triangles read [0, 0, 0], which renderers draw as nothing), and is_vertex_alive / is_triangle_alive tell them apart. Only Mesh::compact renumbers slots.

Implementations§

Source§

impl Mesh

Source

pub fn ensure_adjacency(&mut self) -> Result<()>

Builds the adjacency table if it is not cached. It is cached until the next topology change (commit, undo or redo that adds, removes or rewrites triangles).

Source

pub fn adjacency(&self) -> Option<&Adjacency>

The cached adjacency table, if Mesh::ensure_adjacency built it and no topology change has happened since.

Source

pub fn step_adjacency( &mut self, build: &mut AdjacencyBuild, budget: usize, ) -> Result<bool>

Mesh::ensure_adjacency in steps: runs build over up to budget more elements and, once it is done, caches its table. Returns whether the adjacency is cached, at once when it already is. When the mesh changed since build started, build starts over first. The table is the same as from Mesh::ensure_adjacency, entry for entry.

§Errors

As for Mesh::ensure_adjacency; build then starts over.

Source§

impl Mesh

Source

pub fn compact(&mut self) -> Result<Remap>

Removes dead slots and renumbers alive vertices and triangles in their current order. All existing patches become stale (StalePatch); use crate::History::compact to clear a history at the same time. Channels dropped by crate::Transaction::drop_channel are then gone for good.

Failure-atomic: if memory runs out, the mesh is left unchanged.

Source§

impl Mesh

Source

pub fn ensure_incidence(&mut self) -> Result<()>

Builds the vertex → triangles index if it is not cached. Once built, it follows edits, rollbacks, undo and redo. It is dropped by Mesh::compact, by edits that leave so many rewritten rows that rebuilding is cheaper, and if memory runs out while following an edit.

Source

pub fn incidence(&self) -> Option<&Incidence>

The cached index, if Mesh::ensure_incidence built it. None inside a transaction that changed topology, until it commits or rolls back.

Source

pub fn step_incidence( &mut self, build: &mut IncidenceBuild, budget: usize, ) -> Result<bool>

Mesh::ensure_incidence in steps: runs build over up to budget more elements and, once it is done, caches its index. Returns whether the index is cached, at once when it already is. When the mesh changed since build started, build starts over first. The index is the same as from Mesh::ensure_incidence, entry for entry.

§Errors

As for Mesh::ensure_incidence; build then starts over.

Source§

impl Mesh

Source

pub fn new() -> Self

An empty mesh with its origin at zero.

Source

pub fn from_buffers(positions: &[f32], indices: &[u32]) -> Result<Self>

Builds a mesh from flat [x, y, z, ...] positions and [a, b, c, ...] indices.

Source

pub fn from_buffers_f64(positions: &[f64], indices: &[u32]) -> Result<Self>

Builds a mesh from double-precision positions. The origin is set to the center of the bounding box and positions are stored as f32 offsets from it, which keeps precision for coordinates far from zero. Every coordinate, the computed origin and every offset (as an f32) must be finite.

Source

pub fn from_buffers_f64_with_origin( positions: &[f64], indices: &[u32], origin: [f64; 3], ) -> Result<Self>

Builds a mesh from double-precision positions relative to a given origin: positions are stored as (p - origin) in f32. Every coordinate, the origin and every offset (as an f32) must be finite.

Source

pub fn uid(&self) -> u64

Process-unique id of this mesh. Patches only apply to the mesh that created them.

Source

pub fn revision(&self) -> u64

Changes on every commit, undo and redo. Equal revisions mean equal content.

Source

pub fn epoch(&self) -> u32

Changes whenever Mesh::compact renumbers slots. Data indexed by slot id (such as an acceleration structure) is stale once the epoch differs.

Source

pub fn origin(&self) -> [f64; 3]

World-space origin that positions are relative to.

Source

pub fn vertex_slots(&self) -> usize

Number of vertex slots, alive or dead. Render buffers use this length.

Source

pub fn triangle_slots(&self) -> usize

Number of triangle slots, alive or dead.

Source

pub fn vertex_count(&self) -> usize

Number of alive vertices.

Source

pub fn triangle_count(&self) -> usize

Number of alive triangles.

Source

pub fn is_vertex_alive(&self, v: VertexId) -> bool

Source

pub fn is_triangle_alive(&self, t: TriangleId) -> bool

Source

pub fn position(&self, v: VertexId) -> Option<[f32; 3]>

Position relative to Mesh::origin, or None for a dead or missing vertex.

Source

pub fn world_position(&self, v: VertexId) -> Option<[f64; 3]>

Position in world space (origin added in f64).

Source

pub fn positions(&self) -> &[[f32; 3]]

Slot-aligned positions, including dead slots.

Source

pub fn triangle(&self, t: TriangleId) -> Option<[VertexId; 3]>

Vertex ids of a triangle, or None for a dead or missing triangle.

Source

pub fn triangles(&self) -> &[[VertexId; 3]]

Slot-aligned triangles; dead slots read [0, 0, 0].

Source

pub fn corner_count(&self, v: VertexId) -> u32

How many triangle corners use vertex v (a vertex repeated in one triangle counts twice).

Source

pub fn free_vertex_slots(&self) -> &[VertexId] ⓘ

Dead vertex slots ready for reuse.

Source

pub fn free_triangle_slots(&self) -> &[TriangleId] ⓘ

Dead triangle slots ready for reuse.

Source

pub fn add_channel(&mut self, desc: ChannelDesc) -> Result<()>

Adds a channel filled with its default value. Adding a channel is not undoable.

Source

pub fn add_channel_with_values( &mut self, desc: ChannelDesc, values: &[f32], ) -> Result<()>

Adds a channel holding values (width per vertex slot) from the start. Like Mesh::add_channel, not undoable and no edit: no undo step and no journal entry, whatever the channel’s size.

§Errors

StoreError::LengthMismatch for a wrong length, or as for Mesh::add_channel. The mesh is then unchanged.

Source

pub fn add_uvs(&mut self, uvs: &[f32]) -> Result<()>

Adds the UV channel (UV_CHANNEL) with uvs: 2 finite values per vertex slot. Like Mesh::add_channel, not undoable. Meant for a mesh being set up, before any edit.

§Errors

StoreError::LengthMismatch for a wrong length, StoreError::InvalidArgument for a non-finite value, StoreError::ChannelExists when the mesh already has UVs. The mesh is then unchanged.

Source

pub fn uvs(&self) -> Option<&[f32]>

Slot-aligned UVs, 2 values per vertex, or None for a mesh without them. Shorthand for channel(UV_CHANNEL).

Source

pub fn remove_channel(&mut self, name: &str) -> Result<ChannelDesc>

Removes a channel. Not undoable; patches that recorded it skip it from now on.

Source

pub fn channel_desc(&self, name: &str) -> Option<&ChannelDesc>

Source

pub fn channel(&self, name: &str) -> Option<&[f32]>

Slot-aligned values, width per vertex.

Source

pub fn derived_channel_mut(&mut self, name: &str) -> Result<&mut [f32]>

Writable values of a derived channel. Writes are not recorded for undo.

Source

pub fn release_patch_slots( &mut self, patch: &Patch, state: PatchState, ) -> Result<()>

Returns the slots held by a Patch kept outside crate::History — for example on an application’s own undo stack or a scene-wide history — to the free lists, applying the same rules the history uses internally: PatchState::Applied releases the slots the patch removed, PatchState::Undone the slots it created.

Unlike Patch::release, a patch from another mesh or from before a Mesh::compact is an error (StoreError::PatchMismatch and StoreError::StalePatch, respectively), not a silent skip. Slots that are alive — reused since the patch was made — are skipped.

Release each patch at most once, and only once no history still holds it: releasing twice, or releasing while a history still holds the patch, lists a still-dead slot twice and corrupts slot reuse.

Source§

impl Mesh

Source

pub fn begin_edit(&mut self) -> Transaction<'_>

Opens a transaction. The mesh cannot be used otherwise until it ends.

Trait Implementations§

Source§

impl Debug for Mesh

Shows ids and counts, not the (potentially huge) buffers.

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Mesh

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Mesh

§

impl RefUnwindSafe for Mesh

§

impl Send for Mesh

§

impl Sync for Mesh

§

impl Unpin for Mesh

§

impl UnsafeUnpin for Mesh

§

impl UnwindSafe for Mesh

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.