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
impl Mesh
Sourcepub fn ensure_adjacency(&mut self) -> Result<()>
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).
Sourcepub fn adjacency(&self) -> Option<&Adjacency>
pub fn adjacency(&self) -> Option<&Adjacency>
The cached adjacency table, if Mesh::ensure_adjacency built it and no
topology change has happened since.
Sourcepub fn step_adjacency(
&mut self,
build: &mut AdjacencyBuild,
budget: usize,
) -> Result<bool>
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
impl Mesh
Sourcepub fn compact(&mut self) -> Result<Remap>
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
impl Mesh
Sourcepub fn ensure_incidence(&mut self) -> Result<()>
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.
Sourcepub fn incidence(&self) -> Option<&Incidence>
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.
Sourcepub fn step_incidence(
&mut self,
build: &mut IncidenceBuild,
budget: usize,
) -> Result<bool>
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
impl Mesh
Sourcepub fn from_buffers(positions: &[f32], indices: &[u32]) -> Result<Self>
pub fn from_buffers(positions: &[f32], indices: &[u32]) -> Result<Self>
Builds a mesh from flat [x, y, z, ...] positions and [a, b, c, ...] indices.
Sourcepub fn from_buffers_f64(positions: &[f64], indices: &[u32]) -> Result<Self>
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.
Sourcepub fn from_buffers_f64_with_origin(
positions: &[f64],
indices: &[u32],
origin: [f64; 3],
) -> Result<Self>
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.
Sourcepub fn uid(&self) -> u64
pub fn uid(&self) -> u64
Process-unique id of this mesh. Patches only apply to the mesh that created them.
Sourcepub fn revision(&self) -> u64
pub fn revision(&self) -> u64
Changes on every commit, undo and redo. Equal revisions mean equal content.
Sourcepub fn epoch(&self) -> u32
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.
Sourcepub fn vertex_slots(&self) -> usize
pub fn vertex_slots(&self) -> usize
Number of vertex slots, alive or dead. Render buffers use this length.
Sourcepub fn triangle_slots(&self) -> usize
pub fn triangle_slots(&self) -> usize
Number of triangle slots, alive or dead.
Sourcepub fn vertex_count(&self) -> usize
pub fn vertex_count(&self) -> usize
Number of alive vertices.
Sourcepub fn triangle_count(&self) -> usize
pub fn triangle_count(&self) -> usize
Number of alive triangles.
pub fn is_vertex_alive(&self, v: VertexId) -> bool
pub fn is_triangle_alive(&self, t: TriangleId) -> bool
Sourcepub fn position(&self, v: VertexId) -> Option<[f32; 3]>
pub fn position(&self, v: VertexId) -> Option<[f32; 3]>
Position relative to Mesh::origin, or None for a dead or missing vertex.
Sourcepub fn world_position(&self, v: VertexId) -> Option<[f64; 3]>
pub fn world_position(&self, v: VertexId) -> Option<[f64; 3]>
Position in world space (origin added in f64).
Sourcepub fn triangle(&self, t: TriangleId) -> Option<[VertexId; 3]>
pub fn triangle(&self, t: TriangleId) -> Option<[VertexId; 3]>
Vertex ids of a triangle, or None for a dead or missing triangle.
Sourcepub fn corner_count(&self, v: VertexId) -> u32
pub fn corner_count(&self, v: VertexId) -> u32
How many triangle corners use vertex v (a vertex repeated in one triangle counts twice).
Sourcepub fn free_vertex_slots(&self) -> &[VertexId] ⓘ
pub fn free_vertex_slots(&self) -> &[VertexId] ⓘ
Dead vertex slots ready for reuse.
Sourcepub fn free_triangle_slots(&self) -> &[TriangleId] ⓘ
pub fn free_triangle_slots(&self) -> &[TriangleId] ⓘ
Dead triangle slots ready for reuse.
Sourcepub fn add_channel(&mut self, desc: ChannelDesc) -> Result<()>
pub fn add_channel(&mut self, desc: ChannelDesc) -> Result<()>
Adds a channel filled with its default value. Adding a channel is not undoable.
Sourcepub fn add_channel_with_values(
&mut self,
desc: ChannelDesc,
values: &[f32],
) -> Result<()>
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.
Sourcepub fn add_uvs(&mut self, uvs: &[f32]) -> Result<()>
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.
Sourcepub fn uvs(&self) -> Option<&[f32]>
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).
Sourcepub fn remove_channel(&mut self, name: &str) -> Result<ChannelDesc>
pub fn remove_channel(&mut self, name: &str) -> Result<ChannelDesc>
Removes a channel. Not undoable; patches that recorded it skip it from now on.
pub fn channel_desc(&self, name: &str) -> Option<&ChannelDesc>
Sourcepub fn derived_channel_mut(&mut self, name: &str) -> Result<&mut [f32]>
pub fn derived_channel_mut(&mut self, name: &str) -> Result<&mut [f32]>
Writable values of a derived channel. Writes are not recorded for undo.
Sourcepub fn release_patch_slots(
&mut self,
patch: &Patch,
state: PatchState,
) -> Result<()>
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
impl Mesh
Sourcepub fn begin_edit(&mut self) -> Transaction<'_>
pub fn begin_edit(&mut self) -> Transaction<'_>
Opens a transaction. The mesh cannot be used otherwise until it ends.