Skip to main content

Scene

Struct Scene 

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

Several meshes, each with a BVH and a placement in the world.

Implementations§

Source§

impl Scene

Source

pub fn boolean( &mut self, a: MeshId, b: MeshId, op: BooleanOp, ) -> Result<BooleanReport>

Combines mesh B into mesh A: union, subtract or intersect as placed in the world. The result replaces A with A’s placement, so the world shape is the boolean of the world shapes; B is unchanged. Closed manifold inputs give a closed result; touches leave pinch vertices.

The combination runs as one edit of A, so it undoes in one step. Combining a mesh with itself is a no-op for union and intersect (nothing is recorded), and clears it for subtract. Only positions and triangles cross over: new vertices take channel defaults, and A’s UV channel is dropped (BooleanReport::uvs_dropped). Since UVs do not survive, a mesh with UVs is read with exactly coincident vertices merged, so seams do not make a closed surface count as open; every input check below applies to the merged geometry. B is unchanged, and undo restores A’s split vertices.

§Errors

[SceneError::UnknownMesh] for a stale id; [SceneError::InvalidInput] when an input is not closed, manifold, consistently wound or free of degenerate, duplicate and self-intersecting triangles, or when a mapped position leaves f32 range; [SceneError::Ops], [SceneError::Query], [SceneError::Store] or [SceneError::StaleBvh] from the plan, the bakes and the edit. A failed boolean changes nothing. A stale Manual BVH fails the query with [SceneError::StaleBvh], like the pair queries.

Source§

impl Scene

Source

pub fn find_contacts( &mut self, margin: f64, filter: &ContactFilter, out: &mut Vec<Contact>, ) -> Result<usize>

Appends a Contact for every mesh pair (of filter, or of the whole scene) whose surfaces are within margin of each other as placed in the world, sorted by (a, b), and returns how many were appended. Elements already in out stay in front.

The broadphase keeps the pairs whose world boxes (BVH root boxes placed by the rigid transforms) are within margin, padded so that it never drops a pair Phase 3b would report. For each, in A’s space: intersecting comes from fast_mesh_query::intersects; distance is 0 when intersecting, else from fast_mesh_query::mesh_distance with margin rounded up to f32, and a pair whose distance exceeds the exact margin is not reported; the triangle lists come from fast_mesh_query::triangles_near with the rounded-up margin (see Scene::triangles_near).

With filter.pairs, each pair may be given either way round and more than once; only the listed meshes’ BVHs are brought up to date. Without, every Lazy BVH is (§15.4).

§Errors

SceneError::InvalidInput for a negative or NaN margin or a pair naming one mesh twice; SceneError::UnknownMesh for a stale id in the filter; then a BVH or memory error from a Lazy update, SceneError::StaleBvh for the lowest stale Manual mesh involved, or a memory error while collecting. On any error out keeps its length.

Source§

impl Scene

Source

pub fn cut_by_plane( &mut self, id: MeshId, options: &CutOptions, ) -> Result<CutReport>

Cuts the mesh with a world plane: the + side (signed_distance >= 0) stays on the mesh and the - side is added as a new mesh, both with the mesh’s placement, so the world shape is kept. With options.cap (the usual case) both openings are closed with flat, unfaired patches; without it both parts keep the open rim. Cutting a closed mesh with cap yields two closed meshes. On a mesh with UVs, closed means closed by exact position, so seams count as closed. A rim that runs into a real boundary stays open; on a mesh without UVs, split vertices are such a boundary, so weld them first.

The cut runs as one edit of the mesh, so it undoes in one step; the added mesh is permanent, like the removed source of Scene::join. Only positions and triangles cross over: the added mesh has no normals, colouring, fields or section entries, and new vertices take channel defaults (crossing vertices on the kept side interpolate their parents). UVs carry over to both sides, interpolated at the crossing vertices and across the caps.

§Errors

[SceneError::UnknownMesh] for a stale id; [SceneError::InvalidInput] when the plane does not cut the mesh, or a rim cannot be capped; [SceneError::Ops] or [SceneError::Store] from the cut or the add. A failed cut changes nothing. If adding the removed side fails (out of memory), the cut of the original stays recorded and the added mesh is missing.

Source§

impl Scene

Source

pub fn add_distance_field(&mut self, desc: DistanceField) -> Result<FieldId>

Registers a signed distance field on mesh desc.on, measured to the meshes desc.to, and returns its id. Its values go into a derived channel field:<name> on desc.on, readable with Scene::field_values or through Scene::mesh; they are not undoable. With several targets, a vertex’s value is the smallest over them, and Scene::field_nearest tells which target it came from.

The field follows the UpdateMode of desc.on: an Eager field is computed right away and after every edit, placement change, undo, redo or cancel touching desc.on or a target; a Lazy one by Scene::flush or Scene::update_fields; a Manual one only by Scene::update_fields. Until then its values are NaN.

The targets’ BVHs are brought up to date under the query rules (a Lazy one is updated) and their sign data built here, so that Scene::field_status can report their topology at once.

A position-only edit of a target mesh refits its pseudonormal sign data around the dirty vertices; any other edit rebuilds it over the whole mesh (O(n), about 150 ms at 1M triangles, more after a topology edit, which drops the cached adjacency). Placement changes and edits of desc.on do not rebuild it.

§Errors

SceneError::UnknownMesh; SceneError::InvalidInput when to is empty, holds on or a mesh twice, max_distance is negative or NaN, or on already has a field of that name; SceneError::StaleBvh when a target is a stale Manual mesh; a BVH, field or memory error. The scene is unchanged on error.

Source

pub fn add_distance_field_deferred( &mut self, desc: DistanceField, ) -> Result<FieldId>

Registers a field as Scene::add_distance_field does, but computes nothing yet: no sign data are built and no BVH is brought up to date, whatever the mode of desc.on. The field is due until an update computes it: Scene::field_step (an Eager field), Scene::field_step_field, Scene::update_fields, Scene::flush (Eager and Lazy) or, unless deferred, the next change to one of its meshes (Eager). Until then its values are NaN and Scene::field_status reports placeholder sign data (see Scene::field_target_status). Computed in steps, its values, colours and reports are the same, bit for bit, as from Scene::add_distance_field.

§Errors

SceneError::UnknownMesh; SceneError::InvalidInput as for Scene::add_distance_field; a memory error. The scene is unchanged on error. Errors of the BVHs and sign data come from the update that computes the field.

Source

pub fn withdraw_field(&mut self, id: FieldId) -> Result<bool>

Removes a field that has never been computed, as if it had never been added: unlike Scene::remove_field nothing is reported. Returns false, doing nothing, when the field was computed (by any update) or colours its mesh; Scene::remove_field then applies.

§Errors

SceneError::UnknownField for an unknown or removed field.

Source

pub fn add_thickness_field(&mut self, desc: ThicknessField) -> Result<FieldId>

Registers a per-vertex wall-thickness field on mesh desc.on, and returns its id. Its values go into a derived channel field:<name> on desc.on, readable with Scene::field_values or through Scene::mesh; they are not undoable.

The field follows the UpdateMode of desc.on like a distance field: an Eager one is computed right away and after every edit, placement change, undo, redo or cancel touching desc.on; a Lazy one by Scene::flush or Scene::update_fields; a Manual one only by Scene::update_fields. Until then its values are NaN. Every update recomputes every vertex in full (a thickness has no targets to narrow it down to).

A non-uniformly scaled placement is baked into a world-frame copy for the update, so the values are world distances; a uniform scale multiplies the local values, and a rigid placement changes nothing.

§Errors

SceneError::UnknownMesh; SceneError::InvalidInput when max_distance is negative or NaN, or on already has a field of that name; SceneError::StaleBvh when the mesh is a stale Manual mesh; a BVH, field or memory error. The scene is unchanged on error.

Source

pub fn add_thickness_field_deferred( &mut self, desc: ThicknessField, ) -> Result<FieldId>

Scene::add_thickness_field computing nothing yet: the field is due until an update computes it (Scene::field_step (an Eager field), Scene::field_step_field, Scene::update_fields or Scene::flush, unless deferred, the next change to its mesh (an Eager field)). Until then its values are NaN.

§Errors

SceneError::UnknownMesh; SceneError::InvalidInput as for Scene::add_thickness_field; a memory error. The scene is unchanged on error. Errors of the BVH come from the update that computes the field.

Source

pub fn add_curvature_field(&mut self, desc: CurvatureField) -> Result<FieldId>

Registers a per-vertex curvature field on mesh desc.on, and returns its id. Its values go into a derived channel field:<name> on desc.on, readable with Scene::field_values or through Scene::mesh; they are not undoable.

The field follows the UpdateMode of desc.on like a distance field: an Eager one is computed right away and after every edit, placement change, undo, redo or cancel touching desc.on; a Lazy one by Scene::flush or Scene::update_fields; a Manual one only by Scene::update_fields. Until then its values are NaN. Every update recomputes every vertex in full (a curvature has no targets to narrow it down to).

A non-uniformly scaled placement is baked into a world-frame copy for the update, so the values are world curvatures; a uniform scale s divides the local values by s, and a rigid placement changes nothing.

§Errors

SceneError::UnknownMesh; SceneError::InvalidInput when on already has a field of that name; SceneError::StaleBvh when the mesh is a stale Manual mesh; a BVH, field or memory error. The scene is unchanged on error.

Source

pub fn add_curvature_field_deferred( &mut self, desc: CurvatureField, ) -> Result<FieldId>

Scene::add_curvature_field computing nothing yet: the field is due until an update computes it (Scene::field_step (an Eager field), Scene::field_step_field, Scene::update_fields or Scene::flush, unless deferred, the next change to its mesh (an Eager field)). Until then its values are NaN.

§Errors

SceneError::UnknownMesh; SceneError::InvalidInput as for Scene::add_curvature_field; a memory error. The scene is unchanged on error. Errors of the BVH come from the update that computes the field.

Source

pub fn remove_field(&mut self, id: FieldId) -> Result<()>

Removes a field: its channel leaves its mesh, a colouring by it is removed (reported as colors_dirty: None), and the removal is reported in the mesh’s MeshChanges::fields_changed. The id is rejected from then on.

§Errors

SceneError::UnknownField for an unknown or removed field.

Source

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

Brings every field that is not current up to date, whatever the mode of its mesh, bringing the BVHs it needs up to date under the query rules (Lazy ones are updated). Renderers call this (or Scene::flush), then read any number of fields and colours.

§Errors

The first error, for example SceneError::StaleBvh when a BVH a field needs is a stale Manual one: B’s always, A’s when the field must look for A’s triangles near B (after a placement change or an edit of B). Such a field makes every call (and every Scene::flush) return StaleBvh until that BVH is brought up to date with Scene::update. Every field is still attempted; those that failed stay stale and keep their pending changes.

Source

pub fn field_values(&self, id: FieldId) -> Result<&[f32]>

The field’s values, one per vertex slot of its mesh, as of its last update (see Scene::field_status): signed distances, +∞ for far, NaN for dead or unused vertices. A thickness field holds wall thicknesses instead (+∞ past max_distance, NaN where the rays escape), and a curvature field signed mean curvatures in 1/world-unit (NaN for dead or unused vertices). Never updates.

§Errors

SceneError::UnknownField for an unknown or removed field.

Source

pub fn field_nearest(&self, id: FieldId) -> Result<&[u32]>

Per vertex slot of the field’s mesh, as of its last update: the index in Scene::field_targets of the target its value came from (the lowest on a tie), or u32::MAX for none (a +∞ or NaN value, or a slot not computed yet). It can be shorter than the mesh’s slots (slots added since the last update): those slots have none. Thickness and curvature fields have no targets and report none. Never updates.

After a target mesh is removed, and until the field’s next update (at once for an Eager field, unless deferred), the vertices whose value came from it have none here while their value stays finite, and the later indices are shifted down to the remaining targets.

§Errors

SceneError::UnknownField for an unknown or removed field.

Source

pub fn field_targets(&self, id: FieldId) -> Result<&[MeshId]>

The field’s target meshes, in index order. Removing a target mesh removes it from here, shifting the later ones down. Thickness and curvature fields have no targets.

§Errors

SceneError::UnknownField for an unknown or removed field.

Source

pub fn field_target_status(&self, id: FieldId) -> Result<Vec<SignStatus>>

What the latest sign data build found out about each of the field’s targets, in index order. Thickness and curvature fields have no targets. Never updates.

§Errors

SceneError::UnknownField for an unknown or removed field. A target whose sign data were never built (a field added with Scene::add_distance_field_deferred, not computed yet) reports a placeholder: the requested mode (Auto as SignMode::Pseudonormal), not closed, not consistently oriented, and no counts.

Source

pub fn field_status(&self, id: FieldId) -> Result<FieldStatus>

Whether the field is current, and what the latest sign data builds found out about its target meshes, together (see FieldStatus::sign). Thickness and curvature fields have no sign data and report the placeholder (neither closed nor consistently oriented). Never updates.

§Errors

SceneError::UnknownField for an unknown or removed field.

Source

pub fn set_coloring( &mut self, mesh: MeshId, coloring: Option<Coloring>, ) -> Result<()>

Colours mesh from one of its fields, or stops colouring it with None. Every vertex is recoloured from the field’s current values, and reported as colors_dirty: None. Field updates then recolour the vertices whose values changed and report them. Colours are not undoable.

§Errors

SceneError::UnknownMesh; SceneError::UnknownField; SceneError::InvalidInput when the field is not on mesh or the rule is invalid (see ColorRule::validate). The scene is unchanged on error.

Source

pub fn colors(&self, mesh: MeshId) -> Result<Option<&[[u8; 4]]>>

The mesh’s colours, or None when the mesh has no colouring. Never updates.

The slice always holds exactly one RGBA8 per vertex slot (colors(mesh).len() == mesh.vertex_slots()), so it can be indexed by vertex id at any time. The colours follow the field’s values as of its last update; slots added since are coloured from the field’s channel (NaN, so ColorRule::nan) until the field is updated.

§Errors

SceneError::UnknownMesh for a stale id.

Source

pub fn color_values(&self, mesh: MeshId) -> Result<Option<&[f32]>>

The values the mesh’s colours are made from, or None when the mesh has no colouring. Never updates.

A view of the colouring field’s channel, not a copy: the same slice as Scene::field_values of that field, one f32 per vertex slot. It changes only at vertices reported in colors_dirty, so a renderer can mirror it with the colours’ dirty ranges and map values to colours per fragment (color_of at a vertex gives that vertex’s colour).

§Errors

SceneError::UnknownMesh for a stale id.

Source

pub fn coloring(&self, mesh: MeshId) -> Result<Option<&Coloring>>

The mesh’s colouring, or None when the mesh has no colouring. Never updates.

§Errors

SceneError::UnknownMesh for a stale id.

Source

pub fn fields_on(&self, mesh: MeshId) -> Result<Vec<FieldId>>

The ids of the fields on mesh, in the order they were added. Never updates.

§Errors

SceneError::UnknownMesh for a stale id.

Source

pub fn reconfigure_field( &mut self, id: FieldId, max_distance: f64, sign: SignMode, ) -> Result<()>

Changes a field’s max_distance and sign mode, keeping its id, its name, its meshes and any colouring by it. The field is recomputed in full on its next update (at once for an Eager field); until then its values are stale and Scene::field_status reports it as not current, with placeholder sign data when the sign mode changed. A thickness field has no sign mode (sign is ignored for it), and a curvature field has neither (max_distance is ignored for it too: the call still marks it for recompute).

§Errors

SceneError::UnknownField for an unknown or removed field; SceneError::InvalidInput when max_distance is negative or NaN. The scene is unchanged on error.

Source

pub fn field_id(&self, raw: u32) -> Option<FieldId>

The id of the registered field with this FieldId::raw value, or None when there is none (never added, or removed).

Source

pub fn set_defer_fields(&mut self, on: bool)

Defers Eager field updates: with on, the edits, placement changes, undos, redos, cancels and Scene::update calls that would update the Eager fields involving a mesh leave them due instead, for Scene::field_step (or Scene::update_fields or Scene::flush) to bring up to date. Registering a field on an Eager mesh still computes it at once. Leaves an open step unit open.

Turning it off does not bring fields that are already due up to date: they wait for the next change involving their meshes, or for Scene::field_step, Scene::update_fields or Scene::flush.

Source

pub fn set_field_interaction(&mut self, points: Option<usize>) -> Result<()>

Starts (Some(points)) or ends (None) an interaction: a gesture that changes a placement or a mesh many times a second, during which a distance field too large to recompute per update stays live near the contact and is made exact when the gesture ends.

During an interaction, a field with more finite values than points updates at most points vertices closest to the targets (no pair search: a distance changes no faster than the motion, so its last value and how far the meshes have moved since say which can be close), the vertices around an edit, and a sweep of an eighth of points further vertices. The others keep their values, so that nothing turns far or loses its colour; those values are out of date by at most how far the meshes moved since they were computed (for an edit of a target, by how far it moved its surface, away from the edit’s box), and Scene::field_status does not report it. The band of the closest vertices follows the work from the counts alone, so results are the same with parallel on or off, for any thread count. A field of at most points finite values updates exactly as usual.

Ending the interaction recomputes every vertex of the fields it left out of date, at once for Eager meshes unless fields are deferred (see Scene::set_defer_fields and Scene::field_step); the values, colours and reports are then those of an exact update. Starting one again before that keeps them on the tier, and a gesture that changed nothing leaves nothing to recompute. Drops an open step unit when the setting changes.

§Errors

SceneError::InvalidInput when points is Some(0). The scene is unchanged on error.

Source

pub fn field_interaction(&self) -> Option<usize>

The budget of the interaction under way (see Scene::set_field_interaction), if any.

Source

pub fn field_step(&mut self, budget: FieldBudget) -> Result<StepState>

Computes part of the Eager fields that are due, so that a long update can be spread over several calls (a Worker yields between them).

The first call opens a unit: it takes every due field on an Eager mesh (as an Eager update would) and brings the BVHs each reads up to date. Every call, the first included, then advances the unit’s fields in field order, writing nothing: for each, the build of its targets’ sign data when they are not current (about budget times 32 elements of the build per call), its near search (whole parts, about budget times 16 triangle pairs per call), the choice of the vertices it recomputes (see the module docs), and the values of up to budget of those vertices per call. A call that builds sign data or searches does only that. The call that finishes the last field applies every field of the unit together and returns StepState::Done: values, colours and reports are then the same, bit for bit, as from Scene::update_fields at the state the unit opened at.

An open unit, including one opened by Scene::field_step_field, is continued. Any other &mut self call on the scene drops it first (see Scene::abandon_field_step), except Scene::abandon_field_step and Scene::set_defer_fields.

A unit leaves a trace when it is then abandoned: the BVHs it brought up to date stay refitted, and the sign data it finished building stay with their fields, as after any query that needs them. A sign data build it left unfinished is kept with its field, and a later unit resumes it while its mesh and BVH are unchanged. No value, colour, report or pending change depends on whether that happened.

§Errors

Errors are isolated per field, as in Scene::update_fields: a field that fails, when the unit opens (for example SceneError::StaleBvh for a stale Manual mesh) or while it is advanced, is dropped from the unit and stays stale and due, as after a failed Eager update. The other fields go on, and the call that applies them returns the first error in field order instead of StepState::Done. When no due field can be opened, the first error is returned and no unit is opened.

Source

pub fn field_step_field( &mut self, id: FieldId, budget: FieldBudget, ) -> Result<StepState>

Scene::field_step for field id alone, whatever its mesh’s mode: opens a unit over it when it is not current and no unit for it is open (dropping another open unit), or continues its open unit. Returns StepState::Idle when the field is current. The call that finishes it applies it, with the same values, colours and reports as Scene::update_fields would give it. A thickness or curvature field holds no incremental state: stepping it computes it in full at once.

§Errors

SceneError::UnknownField for an unknown or removed field; then as for Scene::field_step.

Source

pub fn abandon_field_step(&mut self)

Drops the open step unit, if any: nothing it computed is written or reported, and its fields stay due. Does nothing when no unit is open. What the unit brought up to date (BVHs, finished sign data) stays so, and an unfinished sign data build is kept; see Scene::field_step.

Source

pub fn field_step_pending(&self) -> bool

Whether a step unit is open (see Scene::field_step).

Source

pub fn field_step_meshes(&self) -> Vec<MeshId>

The meshes the fields of the open step unit are on and measured to, each once, in field order; empty when no unit is open. A change to any of them makes the unit stale.

Source§

impl Scene

Source

pub fn join( &mut self, a: MeshId, b: MeshId, options: &JoinOptions, ) -> Result<JoinReport>

Joins the source mesh into the target: copies the source’s alive positions (mapped into the target’s local frame, so the world shape is kept) and triangles into the target, bridges loop_a to the copied loop_b, and removes the source mesh. The copy and the bridge run in one edit, so they undo together; the removal is permanent, like Scene::remove_mesh.

Only positions and triangles cross over: the source’s channels are dropped, and the target’s channels take their defaults on the new vertices. UVs are the exception: when both meshes have them they carry over, and when only one has them the result has none (JoinReport::uvs_dropped).

§Errors

SceneError::UnknownMesh for a stale id; SceneError::InvalidInput when the two ids are one mesh; SceneError::Ops with OpsError::StaleLoops for a loop that is not there, or OpsError::InvalidInput when the loops cannot bridge (unclean, over max_edges, winding the same way). A failed join changes nothing: both meshes are left as they were. If removing the source fails (out of memory), the joined geometry stays recorded and the source mesh with it.

Source§

impl Scene

Source

pub fn set_normals(&mut self, id: MeshId, on: bool) -> Result<()>

Turns the mesh’s vertex normals on or off (off by default). Turning them on computes them right away, whatever the mesh’s UpdateMode; either switch is reported as normals_dirty: None. Setting the current state again does nothing.

While on, the normals follow the mesh like its BVH: an Eager mesh’s right after every edit, undo, redo and cancel, a Lazy one’s on Scene::flush or Scene::update, a Manual one’s on Scene::update only. A compaction recomputes them in full right away. Placement changes leave them alone: they are mesh-local.

Memory: besides 12 bytes of normal per vertex slot, a snapshot of the triangles (12 bytes per triangle slot) is kept while normals are on, so the old vertices of removed and rewritten triangles are known.

§Errors

SceneError::UnknownMesh, or SceneError::Store when there is no memory for them. The scene is unchanged on error.

Source

pub fn normals(&self, id: MeshId) -> Result<Option<&[[f32; 3]]>>

The mesh’s vertex normals in mesh-local space, one per vertex slot, or None when normals are off. A normal is the normalised sum of the area-weighted normals of the alive triangles using the vertex; a vertex used by none (or only by degenerate ones), dead slots included, reads [0, 0, 0].

The normals of a Lazy or Manual mesh are those of its last update (new vertex slots read zero until then). The slice may differ in length from mesh.vertex_slots() until the next successful update: shorter if memory ran out while following an edit, or longer if the recomputation after a compaction failed.

§Errors

SceneError::UnknownMesh for a stale id.

Source§

impl Scene

Source

pub fn raycast( &mut self, origin: [f64; 3], dir: [f64; 3], opts: &SceneRayOptions, ) -> Result<Option<SceneRayHit>>

The nearest hit of a world ray over every mesh, with opts.min_t <= t <= opts.max_t in world distance. Equal t goes to the lower MeshId; within a mesh, Phase 3’s rule (smallest triangle id) applies.

dir is normalised in f64, so t is a world distance. For each mesh not culled by its world box, the ray is mapped into the mesh’s local space (the origin by the placement inverse, the direction by its linear inverse, in f64, then rounded to f32) and Phase 3’s fast_mesh_query::raycast runs there, with the bounds rounded outward to f32. The affine map keeps the ray parameter, so the local t is the world t up to that rounding; hits are kept only when it lies within the exact f64 bounds, and a hit dropped just below min_t does not hide one beyond it.

Every Lazy BVH is brought up to date first (§15.4).

§Errors

SceneError::InvalidInput for a non-finite origin, a zero or non-finite direction, NaN bounds or min_t > max_t; then a BVH or memory error from a Lazy update, or SceneError::StaleBvh for the lowest stale Manual mesh; then SceneError::InvalidInput for an origin out of f32 range in some mesh’s local space, or a memory error.

Source

pub fn closest_point( &mut self, p: [f64; 3], opts: &SceneClosestOptions, ) -> Result<Option<SceneClosestHit>>

The point of the scene nearest to p, within opts.max_distance. Equal distances go to the lower MeshId; within a mesh, Phase 3’s rule (smallest triangle id) applies.

Meshes are visited by the distance from p to their world box and pruned by the best world distance so far. In each mesh not culled, p is mapped into local space (in f64, then rounded to f32) and Phase 3’s fast_mesh_query::closest_point runs there: with a rigid placement the local distance is the world distance; with a uniform scale the local bound is the world bound divided by the scale and the local distance is multiplied back; with a non-uniform scale the query runs on a world-baked copy of the mesh (see [baked_mesh]). The world distance must then be within the exact bound.

Every Lazy BVH is brought up to date first (§15.4).

§Errors

SceneError::InvalidInput for a non-finite p or a negative or NaN max_distance; then a BVH or memory error from a Lazy update, or SceneError::StaleBvh for the lowest stale Manual mesh; then SceneError::InvalidInput for a p out of f32 range in some mesh’s local space (or in the world, for a non-uniformly scaled mesh), or a memory error.

Source

pub fn closest_point_on( &mut self, id: MeshId, p: [f64; 3], opts: &SceneClosestOptions, ) -> Result<Option<SceneClosestHit>>

Scene::closest_point on mesh id alone. Only that mesh’s BVH is brought up to date (§15.4).

§Errors

SceneError::UnknownMesh for a stale id; then as for Scene::closest_point, with SceneError::StaleBvh only when this mesh is a stale Manual one.

Source

pub fn bvh(&self, id: MeshId) -> Result<&Bvh>

The mesh’s BVH, in mesh-local f32 space, for running Phase 3 queries directly. Never updates it.

§Errors

SceneError::UnknownMesh for a stale id, or SceneError::StaleBvh when the BVH is not current with the mesh (see Scene::is_current); bring it up to date with Scene::update or Scene::flush first.

Source

pub fn relative_transform(&self, a: MeshId, b: MeshId) -> Result<Rigid>

The transform from mesh b’s local space to mesh a’s local space, origins included: the one the pair queries (Scene::intersects, Scene::mesh_distance, Scene::triangles_near) pass to Phase 3, in the convention of Rigid. Its rotation is re-orthonormalised, so it always passes Rigid::validate. Only for rigid pairs: with a scaled placement on either side the relative map is affine, not rigid (pair queries then run on baked copies instead).

§Errors

SceneError::UnknownMesh for a stale id; SceneError::InvalidInput when either placement is scaled.

Source

pub fn world_to_local(&self, id: MeshId, q: [f64; 3]) -> Result<[f64; 3]>

A world point in mesh id’s local coordinates, origin included: S⁻¹ Rᵀ (q - t) - o, in f64.

§Errors

SceneError::UnknownMesh for a stale id.

Source

pub fn local_to_world(&self, id: MeshId, p: [f64; 3]) -> Result<[f64; 3]>

A point in mesh id’s local coordinates in the world, origin included: R (S (o + p)) + t, in f64.

§Errors

SceneError::UnknownMesh for a stale id.

Source

pub fn intersects(&mut self, a: MeshId, b: MeshId) -> Result<bool>

Whether any triangle of mesh a intersects or touches any triangle of mesh b, as placed in the world: Phase 3’s fast_mesh_query::intersects with the relative transform of B’s local space into A’s. Passing the same id twice means two coincident copies, as in Phase 3. Only these two BVHs are brought up to date.

With a scaled placement on either side the query runs on a copy baked into A’s local space (or into the world when A is non-uniformly scaled; see Scene::bake_pair_inner): same result, up to the copy’s f32 rounding.

§Errors

SceneError::UnknownMesh; then a BVH or memory error from a Lazy update, or SceneError::StaleBvh when either is a stale Manual mesh (the lower id first).

Source

pub fn mesh_distance( &mut self, a: MeshId, b: MeshId, max_distance: f64, ) -> Result<Option<SceneMeshDistance>>

The distance between the surfaces of meshes a and b as placed in the world, with a closest pair of points in the world, or None when it is greater than max_distance (inclusive, may be infinite) or a mesh has no triangle.

Phase 3’s fast_mesh_query::mesh_distance runs in A’s space with max_distance rounded up to f32; the result is kept only when its distance is within the exact bound. Distances carry over unchanged with rigid placements, times A’s uniform scale otherwise; with a non-uniformly scaled A the query runs on copies baked into the world (see Scene::bake_pair_inner). Only these two BVHs are brought up to date.

§Errors

SceneError::UnknownMesh; SceneError::InvalidInput for a negative or NaN max_distance; then as for Scene::intersects.

Source

pub fn triangles_near( &mut self, a: MeshId, b: MeshId, margin: f64, out_a: &mut Vec<TriangleId>, out_b: &mut Vec<TriangleId>, ) -> Result<()>

Appends to out_a the triangles of mesh a within margin of mesh b, and to out_b those of b within margin of a, as placed in the world: Phase 3’s fast_mesh_query::triangles_near in A’s space. Elements already in the vectors stay in front; each appended part is ascending without duplicates. Only these two BVHs are brought up to date. With a scaled placement on either side the query runs on a copy baked into A’s local space (or into the world when A is non-uniformly scaled); passing the same id twice lists every alive triangle of the mesh in both vectors.

margin is rounded up to f32. The lists cannot be filtered again per triangle, so when margin is not an f32 value they may hold triangles up to one f32 step (relative 6e-8) beyond it.

§Errors

SceneError::UnknownMesh; SceneError::InvalidInput for a negative or NaN margin; then as for Scene::intersects, or SceneError::Query with OutOfMemory when a vector cannot grow. On any error both vectors keep their lengths.

Source§

impl Scene

Source

pub fn register( &mut self, moving: MeshId, fixed: MeshId, options: &RegisterOptions, ) -> Result<RegisterReport>

Rigidly aligns the mesh moving to the mesh fixed by point-to-plane ICP (fast_mesh_ops::icp()), using points on moving’s surface and fixed’s BVH.

The initial guess is the current placements. ICP is local, so put the meshes roughly in place first, with Scene::set_placement; a good guess is off by a small part of the shape’s features.

Applying. With RegisterOptions::apply (the default) a good result becomes moving’s placement as one undo step, or as part of the open step. Good means converged, with rmse within RegisterOptions::max_rmse and enough points in range (NotApplied says which failed). Anything else changes nothing, whatever the option, but its estimate is returned; set it with Scene::set_placement if it will do.

Undetermined poses. A sphere’s spin, a cylinder’s spin and a plane’s slide are not fixed by the data, though facets or noise can make the iteration settle on some value with a tiny rmse. Those report IcpStatus::Underconstrained, not converged, and list the motions in undetermined. Coarse regular meshes count too: a 16-sided sphere has exact fits 22.5 degrees apart.

Scales. Only rotation and translation are solved. moving’s scale is applied to its points and kept as it is. fixed’s scale, uniform or not, is followed exactly, on a copy of fixed baked through it with its own BVH, so each such call costs a BVH build. Distances and options are in world units either way.

Partial overlap. Set IcpOptions::overlap a little below the fraction of moving that lies over fixed, or nothing is rejected.

Only fixed’s BVH is used, and only it is brought up to date.

§Errors

SceneError::UnknownMesh for a stale id; SceneError::InvalidInput when the ids are one mesh, max_samples is zero or max_rmse is negative or NaN; SceneError::StaleBvh for a stale Manual fixed; SceneError::Ops when a mesh has no triangles, an option is invalid, or a placement takes the points out of f32 range in fixed’s frame. On error the scene is unchanged.

Source§

impl Scene

Source

pub fn new(options: SceneOptions) -> Scene

An empty scene.

Source

pub fn add_mesh(&mut self, mesh: Mesh, options: MeshOptions) -> Result<MeshId>

Adds a mesh, building its BVH, and returns its id. With MeshOptions::defer_bvh a Lazy or Manual mesh builds its BVH on first use instead (its first update, query or flush), since nothing needs it before then.

§Errors

SceneError::InvalidInput for an invalid placement, or a BVH or memory error from the build. An invalid policy is refused before anything is built. The scene is unchanged on error.

Source

pub fn add_mesh_built(&mut self, build: MeshBuild) -> Result<MeshId>

Adds a mesh built in steps by build (see MeshBuild), first finishing what is left of its BVH and normals, and returns its id. The mesh, its BVH, its normals and everything reported are the same as from Scene::add_mesh with the same mesh and options, followed by Scene::set_normals when the build has normals on.

§Errors

As for Scene::add_mesh. The scene is unchanged on error.

Source

pub fn remove_mesh(&mut self, id: MeshId) -> Result<Mesh>

Removes a mesh and returns it. The id never matches again. Its history entries (undo, redo and in an open step) are dropped, steps left empty with them, and its patches release the slots they reserve. The removal shows up in every subscriber’s next Scene::take_changes_for, unless the mesh was added since that subscriber’s last call.

The fields on the mesh and those measured to it alone are removed with it (see Scene::remove_field), and so are colourings by them. A field measured to it and to other meshes keeps the others: it is recomputed in full, at once when it is Eager. The mesh leaves every section selecting it, which is reported in its final MeshChanges::sections_changed.

§Errors

SceneError::UnknownMesh for a stale id.

Source

pub fn edit<R, E: Into<SceneError>>( &mut self, id: MeshId, f: impl FnOnce(&mut Transaction<'_>) -> Result<R, E>, ) -> Result<R>

Runs f in a transaction on mesh id, commits it, and records the patch in the history: in the open step, or as a step of its own when none is open. Recording drops the redo stack. The changes are added to the mesh’s report and to its BVH’s pending changes; an Eager BVH is then brought up to date, and so are the Eager fields and section entries involving the mesh (a failed update leaves them stale and never fails the edit).

An empty transaction records and reports nothing.

If the Eager BVH update fails (for example out of memory), the edit still succeeds: the BVH keeps its pending changes and is treated like Lazy until Scene::update, Scene::flush or a query updates it.

f may fail with any error that converts into SceneError: a store error, or an OpsError from a repair operation, which becomes SceneError::Ops (out-of-memory becomes SceneError::Store, however it was raised). A closure whose body never fails cannot infer its error type (E0283) and must name it, for example scene.edit(id, |_| Ok::<(), StoreError>(())).

§Errors

SceneError::UnknownMesh for a stale id; f’s error, converted (for example SceneError::Store or SceneError::Ops), when it fails; or SceneError::Store when the commit fails or there is no memory to record the patch. The transaction is then rolled back and the scene (including an open step) is unchanged.

Source

pub fn begin_step(&mut self)

Opens a history step, or one more nesting level of the open step. Edits and placement changes until the matching Scene::end_step are undone and redone together, across meshes.

Source

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

Ends one nesting level of the open step; the outermost call closes it. A step with no entries is not recorded. Closing may evict the oldest steps to meet the history budget.

§Errors

SceneError::StepNotOpen when no step is open.

Source

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

Reverts the open step’s entries, in reverse order, and discards the step, however deeply nested (for example on Esc mid-drag). The reverts are reported and update BVHs like an undo.

§Errors

SceneError::StepNotOpen when no step is open. A store error (for example out of memory) leaves the meshes and the open step unchanged; SceneError::Corrupted means that even restoring them failed, with the consequences described for Scene::undo.

Source

pub fn undo(&mut self) -> Result<bool>

Closes an open step, then undoes the latest step: its entries are reverted in reverse order, all or nothing. Returns false when there is nothing to undo. The changes are reported and reach the BVHs as for Scene::edit; a placement entry gets its old value back and is reported as placement_changed.

A non-empty open step is the latest step, and it is undone even when it is larger than the whole history budget (Ctrl+Z mid-drag undoes the drag). The budget is applied afterwards, which may evict the oldest undo steps and, for a step larger than the budget, drop it from the redo stack again.

§Errors

A store error (for example out of memory): the meshes, both stacks and an open step are then unchanged (the step stays open). SceneError::Corrupted if restoring them after such an error failed too: the failed step is dropped from its stack (an open step is discarded), the meshes it edits may be partly changed, each of them is reported as fully changed (changes: None) and its BVH is rebuilt from scratch on its next update (right away for Eager), and each mesh with a placement entry in it is reported as placement_changed. The history may no longer match the meshes, so the caller should consider Scene::clear_history.

Source

pub fn redo(&mut self) -> Result<bool>

Closes an open step, then redoes the latest undone step: its entries are re-applied in order, all or nothing. Returns false when there is nothing to redo. Reporting and errors as for Scene::undo.

§Errors

As for Scene::undo.

Source

pub fn can_undo(&self) -> bool

True if Scene::undo would undo something, counting a non-empty open step.

Source

pub fn can_redo(&self) -> bool

True if Scene::redo would redo something.

Source

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

Closes an open step, then drops every undo and redo step, releasing the slots their patches reserve. The meshes are not changed.

§Errors

None at present; the Result leaves room for future checks.

Source

pub fn set_mode(&mut self, id: MeshId, mode: UpdateMode) -> Result<()>

Sets when the mesh’s BVH is brought up to date. Switching to UpdateMode::Eager updates a stale BVH right away; if that update fails, the mode is still set and the BVH stays pending, as after a failed Eager update in Scene::edit.

§Errors

SceneError::UnknownMesh for a stale id.

Source

pub fn mode(&self, id: MeshId) -> Result<UpdateMode>

When the mesh’s BVH is brought up to date (see Scene::set_mode).

§Errors

SceneError::UnknownMesh for a stale id.

Source

pub fn update(&mut self, id: MeshId) -> Result<()>

Brings the mesh’s BVH, and its normals if they are on, up to date now, whatever its mode. Eager fields involving the mesh that were left stale (for example by this BVH being a stale Manual one) then catch up, unless Eager field updates are deferred (see Scene::set_defer_fields): they then stay due. Every stale section entry of the mesh catches up too, whatever its mode.

§Errors

SceneError::UnknownMesh, or a BVH or memory error from the update of the BVH or the normals (both are attempted). On error they keep their pending changes. Then the first section error (for example out of memory); such entries stay stale.

Source

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

Brings every Lazy BVH up to date, and every Eager one left stale by a failed update, and the same for the normals (see Scene::set_normals); then does the same for the fields, which follow the mode of the mesh they are on (see Scene::update_fields), and for the section entries, which follow the mode of their mesh (see Scene::update_sections). Manual BVHs, and fields and section entries on Manual meshes, are left alone.

§Errors

The first BVH, memory or field error, for example SceneError::StaleBvh for a field measured to a stale Manual mesh: such a field makes every flush return StaleBvh until that BVH is brought up to date with Scene::update. Every mesh and field is still attempted; those that failed keep their pending changes.

Source

pub fn take_changes(&mut self) -> Vec<MeshChanges>

Everything that happened to the meshes since the last call, one entry per affected mesh in id order, then resets every report of the default subscriber. Other subscribers keep theirs (see Scene::subscribe).

A mesh added and removed between two calls is not reported, and neither is a mesh whose changes cancel out (for example vertices added and removed again).

Source

pub fn subscribe(&mut self) -> SubscriberId

Adds a consumer of change reports and returns its id. It starts with a clean report for every mesh, so it sees only what happens from now on, except for colours: a mesh that already has a colouring starts with colors_dirty: None, so the subscriber reads every colour once. It drains its reports with Scene::take_changes_for. Every subscriber is told about the same changes, merged the same way. A subscriber that never drains keeps accumulating reports (merged change sets and removals) until it is drained or unsubscribed.

Source

pub fn unsubscribe(&mut self, id: SubscriberId) -> Result<()>

Removes a subscriber and drops its pending reports. Its id is rejected from then on.

§Errors

SceneError::InvalidInput for an unknown or already removed id, or for the default subscriber (which backs Scene::take_changes).

Source

pub fn take_changes_for(&mut self, id: SubscriberId) -> Result<Vec<MeshChanges>>

Scene::take_changes for subscriber id: everything that happened to the meshes since its last call (or since it subscribed), one entry per affected mesh in id order, then resets its reports.

§Errors

SceneError::InvalidInput for an unknown or removed subscriber.

Source

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

Adds a channel to the mesh, filled with its default value. Not undoable, as in the store; reported in MeshChanges::channels_written. Names starting with field: are reserved for the scene’s fields.

§Errors

SceneError::InvalidInput for a reserved name, SceneError::UnknownMesh, or the store’s error (for example a duplicate name). The scene is unchanged on error.

Source

pub fn capture_rest_sizes( &mut self, id: MeshId, only_if_missing: bool, ) -> Result<()>

Records the mesh’s rest sizes for split_stretched; see capture_rest_sizes. Not an edit: no undo step and no change report, since no geometry changed and nothing draws this channel. With only_if_missing, valid rest sizes stay as they are (ensure_rest_sizes).

§Errors

SceneError::UnknownMesh, or SceneError::Ops when memory runs out.

Source

pub fn ensure_incidence(&mut self, id: MeshId) -> Result<()>

Builds the mesh’s vertex index if it is not cached, so that an operation run next can follow it instead of scanning every triangle.

§Errors

SceneError::UnknownMesh, or the store’s error when memory runs out.

Source

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

Removes a channel from the mesh and returns its description. Not undoable, as in the store; reported in MeshChanges::channels_written. Recorded patches skip the removed channel from then on, so undo and redo will not restore the values of a removed source channel.

§Errors

SceneError::InvalidInput for a reserved name (starting with field:), SceneError::UnknownMesh, or the store’s error for an unknown name.

Source

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

Writable values of a derived channel. Writes are not undoable, as in the store. The call itself is reported in MeshChanges::channels_written, since the slice may be written after it returns.

§Errors

SceneError::InvalidInput for a reserved name (starting with field:), SceneError::UnknownMesh, or the store’s error for an unknown or non-derived channel.

Source

pub fn compact(&mut self, id: MeshId) -> Result<Remap>

Removes the mesh’s dead slots and renumbers the rest (see Mesh::compact). The mesh’s recorded patches no longer apply, so its edit entries leave the undo and redo stacks and an open step; steps left empty are dropped. Its placement entries stay valid and are kept. Nothing is released: the reserved slots no longer exist. Its BVH is rebuilt whatever its mode, and the next Scene::take_changes reports it as fully changed (changes: None, colors_dirty: None, normals_dirty: None). Its field channels and colours are remapped with it, and its normals recomputed in full, whatever its mode; the fields involving it are recomputed in full on their next update, and so are its section entries.

If the rebuild (or the normals) fails, compaction still succeeds and the BVH (or the normals) stays pending, as after a failed Eager update in Scene::edit.

§Errors

SceneError::UnknownMesh, or a store error from the compaction; the scene is then unchanged.

Source

pub fn mesh(&self, id: MeshId) -> Result<&Mesh>

The mesh behind id.

§Errors

SceneError::UnknownMesh for a stale id.

Source

pub fn ids(&self) -> impl Iterator<Item = MeshId>

The ids of all meshes, in index order.

Source

pub fn mesh_id(&self, index: u32, generation: u32) -> Option<MeshId>

The id of the live mesh with this MeshId::index and MeshId::generation, or None when there is none (never added, or removed). For ids passed back across an FFI boundary: a stale or made-up pair cannot become a live id.

Source

pub fn placement(&self, id: MeshId) -> Result<Placement>

Where the mesh sits in the world.

§Errors

SceneError::UnknownMesh for a stale id.

Source

pub fn set_placement(&mut self, id: MeshId, placement: Placement) -> Result<()>

Moves the mesh. Stores the placement, reports it as placement_changed and records the old and new value in the history (in the open step, or as a step of its own), which drops the redo stack. Setting the current placement again records and reports nothing. No BVH is touched; Eager fields and section entries involving the mesh are updated (a failure leaves them stale).

Within an open step, consecutive placement changes of the same mesh merge into one entry that keeps the first old value and the last new one, so a drag of any length records one entry and undo still restores the placement from before the drag. Any other entry in between (an edit, or another mesh’s placement) starts a new entry.

§Errors

SceneError::UnknownMesh, SceneError::InvalidInput when the rotation is not a proper rotation or the scale is not finite and positive, or SceneError::Store when there is no memory to record it. The scene is unchanged on error.

Source

pub fn is_current(&self, id: MeshId) -> Result<bool>

Whether the mesh’s BVH is up to date with the mesh.

§Errors

SceneError::UnknownMesh for a stale id.

Source

pub fn bounds(&self, id: MeshId) -> Result<Option<Aabb>>

The box around the vertices the live triangles use, in the mesh’s stored local coordinates, or None without live triangles. Dead slots keep stale positions, and a live vertex no live triangle uses is not drawn either, so neither widens it.

§Errors

SceneError::UnknownMesh for a stale id.

Source§

impl Scene

Source

pub fn dab(&mut self, id: MeshId, dab: &Dab) -> Result<DabReport>

Applies one brush dab as one edit: the same history, reports and failure behaviour as Scene::edit with the matching deform function, and the same result, bit for bit, except that a vertex no triangle uses is out of the brush’s reach. The cost follows the vertices under the brush, plus a walk down the BVH, however large the mesh is; where the BVH cannot serve (stale under UpdateMode::Manual) it scans the mesh instead.

The first dab on a mesh builds its vertex-to-triangles index, once.

§Errors

As for Scene::edit with the deform function: SceneError::UnknownMesh for a stale id, SceneError::Ops for an invalid brush, SceneError::Store when memory runs out. Nothing changes in any of these cases.

Source

pub fn dab_protected( &mut self, id: MeshId, dab: &Dab, vertices: &[VertexId], weights: &[f32], ) -> Result<DabReport>

Scene::dab under with_protection: each listed vertex’s move is scaled by its weight, at a cost that follows the brush region plus the list. List only what the brush can reach.

A dab with every vertex under its brush held fully (weight 0) moves nothing, so it edits nothing either: it reports 0 and leaves no undo step.

§Errors

As for Scene::dab, and as check_protection for the list. Nothing changes in any of these cases.

Source§

impl Scene

Source

pub fn add_section(&mut self, desc: SectionDesc) -> Result<SectionId>

Registers a plane section of the meshes desc.meshes and returns its id. Sections are not in the history: undo does not move planes.

Each selected mesh gets its own SectionResult, which follows the UpdateMode of that mesh: an Eager mesh’s is computed right away and after every edit, placement change, undo, redo or cancel of the mesh, and after every plane or fill change; a Lazy one’s by Scene::flush, Scene::update or Scene::update_sections; a Manual one’s by Scene::update or Scene::update_sections. A failed Eager computation is swallowed and leaves the entry stale. Until its first computation an entry reads as an empty result with status SectionStatus::Stale.

Results that change are reported in the mesh’s MeshChanges::sections_changed.

§Errors

SceneError::UnknownMesh for a stale mesh id; SceneError::InvalidInput for a mesh listed twice; a memory error. Never SceneError::StaleBvh. The scene is unchanged on error.

Source

pub fn remove_section(&mut self, id: SectionId) -> Result<()>

Removes a section. The removal is reported in the MeshChanges::sections_changed of every mesh it selected, and the id is rejected from then on.

§Errors

SceneError::UnknownSection for an unknown or removed section.

Source

pub fn set_section_plane(&mut self, id: SectionId, plane: Plane) -> Result<()>

Moves a section’s plane. Every entry of the section becomes stale (Eager ones are recomputed right away); nothing else is touched. Computing an Eager entry needs a current BVH, so an Eager mesh whose earlier BVH update failed has that update retried here.

§Errors

SceneError::UnknownSection for an unknown or removed section.

Source

pub fn set_section_meshes( &mut self, id: SectionId, meshes: Vec<MeshId>, ) -> Result<()>

Changes the meshes a section cuts. Meshes it keeps keep their entries; added meshes start stale (Eager ones are computed right away); removed meshes drop their entries, which is reported in their MeshChanges::sections_changed.

§Errors

SceneError::UnknownSection; SceneError::UnknownMesh for a stale mesh id; SceneError::InvalidInput for a mesh listed twice; a memory error. Never SceneError::StaleBvh. The scene is unchanged on error.

Source

pub fn set_section_fill(&mut self, id: SectionId, fill: bool) -> Result<()>

Turns a section’s fill on or off. Every entry of the section becomes stale (Eager ones are recomputed right away); nothing else is touched. As with Scene::set_section_plane, an Eager mesh whose earlier BVH update failed has that update retried.

§Errors

SceneError::UnknownSection for an unknown or removed section.

Source

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

Computes every stale section entry, whatever the mode of its mesh, bringing the BVHs it needs up to date under the query rules (Lazy ones are updated). Renderers call this (or Scene::flush), then read any number of results.

§Errors

The first error, for example SceneError::StaleBvh for an entry whose mesh has a stale Manual BVH: such an entry stays stale, and makes every call return StaleBvh until that BVH is brought up to date with Scene::update. Every entry is still attempted.

Source

pub fn section(&self, id: SectionId, mesh: MeshId) -> Result<&SectionResult>

The section’s result for mesh as of its last computation (see Scene::section_status); empty before the first one. Never updates.

§Errors

SceneError::UnknownSection; SceneError::UnknownMesh for a stale mesh id; SceneError::InvalidInput for a live mesh the section does not select.

Source

pub fn section_desc(&self, id: SectionId) -> Result<&SectionDesc>

The section’s description as last set: its plane (the one Scene::set_section_plane gave, which results not yet recomputed may lag behind; see Scene::section_plane), meshes and fill.

§Errors

SceneError::UnknownSection for an unknown or removed section.

Source

pub fn section_status( &self, id: SectionId, mesh: MeshId, ) -> Result<SectionStatus>

Whether the section’s result for mesh is current. Never updates.

§Errors

As for Scene::section.

Source

pub fn section_plane( &self, id: SectionId, mesh: MeshId, ) -> Result<Option<Plane>>

The world plane the section’s result for mesh was computed with, whose (u, v) frame its 2D points and fill are in; None before the first computation. It differs from the section’s plane while a plane move is not yet computed. Never updates.

§Errors

As for Scene::section.

Source

pub fn section_revision(&self, id: SectionId, mesh: MeshId) -> Result<u64>

How many times the section’s result for mesh has changed: 0 before its first computation, then up by one per computation whose result differs (a recompute with an identical result leaves it alone). Bindings cache per-result data (like GPU buffers) against it instead of draining a subscriber. Never updates.

§Errors

As for Scene::section.

Source

pub fn section_gap( &self, id: SectionId, a: MeshId, b: MeshId, ) -> Result<Option<Gap>>

The closest pair between the contours of meshes a and b in the section, measured in the plane, with its points in the world; None when either has no contour segments. Never updates: it reads the last computed results, so for a stale entry (see Scene::section_status) it describes the scene as of that computation. A gap is only defined within one plane: when the two results were computed with different planes (one was updated after a plane move, the other not yet), it is None; call Scene::update_sections first.

§Errors

As for Scene::section, for either mesh; SceneError::InvalidInput when a and b are the same mesh; a memory error.

Source

pub fn section_id(&self, raw: u32) -> Option<SectionId>

The id of the section with this SectionId::raw value, or None when there is none (never added, or removed).

Auto Trait Implementations§

§

impl Freeze for Scene

§

impl RefUnwindSafe for Scene

§

impl Send for Scene

§

impl Sync for Scene

§

impl Unpin for Scene

§

impl UnsafeUnpin for Scene

§

impl UnwindSafe for Scene

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.