pub struct Model { /* private fields */ }Expand description
A document: topology, placements, geometry, and where every entity came from.
Implementations§
Source§impl Model
impl Model
Sourcepub fn with_tolerances(tolerances: Tolerances) -> Self
pub fn with_tolerances(tolerances: Tolerances) -> Self
An empty model at a given unit scale.
A document has a scale, and it is the document’s rather than each
call’s: a model authored in metres does not become a model in
millimetres because one caller passed the default. Algorithms still take
a Tolerances argument (that is deliberate, since a caller may want
to work coarser or finer than the document’s own setting for one
operation), but the document says what it was built at, so a
mismatch is visible rather than assumed away.
Sourcepub const fn tolerances(&self) -> Tolerances
pub const fn tolerances(&self) -> Tolerances
The tolerances this document was built at.
Sourcepub fn from_parts(parts: ModelParts) -> OgeomResult<Self>
pub fn from_parts(parts: ModelParts) -> OgeomResult<Self>
Assemble a model from parts read back from a file.
The one way into a Model that does not go through its builders, and
it exists for one reason: a builder mints an identity for every node
it makes (docs/DATA_MODEL.md §8). A document rebuilt through the
builders is therefore a different document from the one that was
written (every EntityId renumbered, every provenance record
replaced by a fresh Primitive one), and every reference into it,
which is the thing provenance exists to keep alive, is dead. Reading a
file has to reproduce the document it describes, identities and all.
This is not a hole in “the builder is the sole mutation path”. Nothing here mutates an existing model; it assembles a new one, and it checks the structural invariants the builders check before handing it back, so a corrupt file is an error, not a model that answers wrongly.
§Errors
OgeomError::Dangling if a node names a
child, a datum, a piece of geometry or an identity that is not there;
OgeomError::Construction if a node’s
data does not match its kind, or a child is of the wrong kind for its
parent.
Sourcepub fn absorb(
&mut self,
parts: ModelParts,
roots: &[Shape],
) -> OgeomResult<Absorbed>
pub fn absorb( &mut self, parts: ModelParts, roots: &[Shape], ) -> OgeomResult<Absorbed>
Absorb another document’s parts into this model.
Model::from_parts lands a document in a fresh model; this lands
one in a model that already has things in it: the operation behind
bringing a serialized tool body into a live document so a boolean can
use it. Everything the parts carry is appended: nodes, datums,
geometry, provenance and identities all keep their relative structure,
shifted past what the model already holds. The result behaves exactly
as if it had been built here, because after the shift it is
indistinguishable from having been.
roots are the shapes the source document named, in the unbound state
a reader leaves them; they come back bound to this model. The returned
Absorbed::entities table says where every source identity landed,
which is what a caller holding references against the source document
resolves them through.
Three deliberate refusals, each an error rather than a guess:
- Units. A document authored at another scale is refused, not rescaled; rescaling is a real feature with real decisions in it, and silently absorbing metres into millimetres is a wrong model.
- Bound handles. Parts whose handles already name an arena did not come from a reader; absorbing them would alias whatever those handles meant elsewhere. Serialization is the one road in.
- A model that reuses slots. Absorbing appends by offset, which
is only sound while each of the target’s arenas hands out fresh
slots in order.
Model::retain_reachableleaves slots empty and never hands them out again, so a retained model absorbs; an arena waiting to refill a freed slot is refused, and the check is what keeps that refill from becoming aliasing.
The current operation is left alone: absorb mints no identities, it
transplants a table, and the absorbed provenance keeps its source
OpIds verbatim, meaningful in the source document’s rebuild, kept
because renumbering them would orphan the source’s own references.
§Errors
OgeomError::Construction for
the three refusals above;
OgeomError::Dangling if the parts
do not describe themselves: a handle that does not resolve, a
derivation from an identity no entry issued, a root naming a node that
is not there.
On an error past the up-front gates, the model’s prior contents are untouched and still fully usable: an absorbed subgraph is self-contained (its shifted handles cannot reach below the append line), and no identity is committed until every check has passed. What a failed absorb can leave behind is unreachable appended entries, which cost memory and mean nothing.
Sourcepub fn bind(&self, shape: &Shape) -> OgeomResult<Shape>
pub fn bind(&self, shape: &Shape) -> OgeomResult<Shape>
Bind an unscoped shape to this model.
A handle rebuilt by a reader names no arena, so it resolves nowhere until it is told which document it belongs to. This is how a reader says so, and it verifies the answer, so a file naming a node that is not there is an error rather than a shape that fails mysteriously later.
It will not re-home a shape that already belongs to another model. That is exactly the mistake scoping exists to catch, and quietly relabelling it would hand back a shape that resolves and answers about the wrong entity.
§Errors
OgeomError::Construction if the shape
already belongs to a different model;
OgeomError::Dangling if it does not resolve
here once bound.
Sourcepub fn bind_location(&self, location: &Location) -> OgeomResult<Location>
pub fn bind_location(&self, location: &Location) -> OgeomResult<Location>
Bind a bare location to this model’s datum store.
The persistence path’s sibling of Model::bind: a location read
from a file names datum handles that are unscoped until the store
that holds them exists. Binding checks them too: a chain naming a
datum not in this model is an error here rather than wherever it is
first resolved.
§Errors
OgeomError::Dangling if the chain
names a datum not in this model.
Sourcepub const fn begin_operation(&mut self) -> OpId
pub const fn begin_operation(&mut self) -> OpId
Begin a new operation, and return its identifier.
Every node created from here on is attributed to it until the next call.
The counter is deterministic (the third operation in a rebuild is
OpId(3) every time), which is what lets provenance survive a parameter
change (docs/DATA_MODEL.md §8).
Sourcepub const fn current_operation(&self) -> OpId
pub const fn current_operation(&self) -> OpId
The operation nodes are currently attributed to.
Sourcepub fn identity_of(&self, shape: &Shape) -> Option<EntityId>
pub fn identity_of(&self, shape: &Shape) -> Option<EntityId>
The stable identity of a shape’s node.
Distinct from its arena handle: the handle says where the data is and dies when the shape is rebuilt, while this says what the entity is and survives.
Sourcepub fn provenance_of(&self, shape: &Shape) -> Option<&Provenance>
pub fn provenance_of(&self, shape: &Shape) -> Option<&Provenance>
Where a shape’s node came from.
Sourcepub const fn provenance(&self) -> &ProvenanceTable
pub const fn provenance(&self) -> &ProvenanceTable
The provenance table.
Sourcepub fn forget_provenance(&mut self, ids: impl IntoIterator<Item = EntityId>)
pub fn forget_provenance(&mut self, ids: impl IntoIterator<Item = EntityId>)
Drop the provenance entries of ids, keeping the ids issued.
What a document reader does with the entities its file left out: no
shape the file carries names them and no kept entry derives from
them, so they answer None as an id from another document does, and
no later entity can take their numbers. Ids without an entry are
passed over.
Sourcepub fn retain_reachable(&mut self, roots: &[Shape]) -> OgeomResult<()>
pub fn retain_reachable(&mut self, roots: &[Shape]) -> OgeomResult<()>
Drop everything roots do not reach, in place.
Kept: every node below a root, the curves, pcurves, surfaces and triangulations those nodes name, and the provenance entries of the identities they carry with every entry those derive from. Every handle into what is kept resolves as before and means the same thing, and a lineage query on a kept shape answers as before. A handle into what is dropped fails to resolve, and no later entity takes its slot or its id, so it never answers about something else. Datums are kept whole: a placement a caller holds keeps resolving.
What is dropped stops costing memory, and a clone costs what is kept. For a model that runs many operations and keeps one result: call it with that result once the model has grown well past what the result reaches.
§Errors
OgeomError::Dangling if a root
does not resolve in this model; nothing is dropped then.
Sourcepub fn roots_of(&self, shape: &Shape) -> Vec<EntityId>
pub fn roots_of(&self, shape: &Shape) -> Vec<EntityId>
Trace a shape back to the entities it ultimately came from.
How a reference into a rebuilt model is resolved: find what the user originally picked, then find what that became.
Sourcepub fn shape_of(&self, id: EntityId) -> Option<Shape>
pub fn shape_of(&self, id: EntityId) -> Option<Shape>
The shape carrying a given identity, if this document has one.
The inverse of Model::identity_of, and the answer to “I kept a
reference and the document has been saved and reloaded since”. A raw
Shape cannot survive that: the reloaded document is a new set of
arenas and Model::bind refuses a handle from another one, on
purpose. An EntityId can, because it names what the entity is
rather than where it sits (docs/DATA_MODEL.md §8), and that is the
whole reason it exists.
Returns the shape in its default placement and orientation. A caller that wants a particular occurrence explores from here.
Sourcepub fn set_derived(
&mut self,
shape: &Shape,
from: &[Shape],
role: Role,
) -> OgeomResult<EntityId>
pub fn set_derived( &mut self, shape: &Shape, from: &[Shape], role: Role, ) -> OgeomResult<EntityId>
Record that a node was derived from other entities.
Overwrites the Primitive attribution a builder assigns by default.
An operation that splits or reshapes existing topology calls this, and
what it records is what a later rebuild will match against.
§Errors
OgeomError::Dangling if the shape does not
resolve in this model.
Sourcepub const fn datums(&self) -> &DatumStore
pub const fn datums(&self) -> &DatumStore
The placement datums.
Sourcepub const fn geometry(&self) -> &GeometryStore
pub const fn geometry(&self) -> &GeometryStore
The geometry.
Sourcepub const fn geometry_mut(&mut self) -> &mut GeometryStore
pub const fn geometry_mut(&mut self) -> &mut GeometryStore
Mutable access to the geometry, for adding curves and surfaces.
A surface rewritten in place through it forgets every face’s kept
box (Model::face_bounds).
Sourcepub fn add_datum(&mut self, transform: Transform) -> DatumId
pub fn add_datum(&mut self, transform: Transform) -> DatumId
Intern a transform for use in placements.
Sourcepub fn node_by_id(&self, id: TShapeId) -> Option<&TShape>
pub fn node_by_id(&self, id: TShapeId) -> Option<&TShape>
The node behind a handle.
Sourcepub fn node_mut(&mut self, shape: &Shape) -> Option<&mut TShape>
pub fn node_mut(&mut self, shape: &Shape) -> Option<&mut TShape>
Mutable access to the node behind a shape’s handle.
For attaching geometry to an entity that already exists: a pcurve joining an edge to a face it has just come to bound. Structural change still goes through the builders; this reaches the node’s data, which no invariant here constrains on its own.
The node may be changed in any way, so the box kept for every face
it is part of (Model::face_bounds) is forgotten, and so is what
is kept of every shape holding it (Model::kept_read). Every shape
holding the node sees the change; an editor starting from a shape it
was given copies what other shapes hold first (Model::unshare).
Sourcepub fn face_bounds(&self, face: &Shape) -> Option<Aabb>
pub fn face_bounds(&self, face: &Shape) -> Option<Aabb>
The box kept for a face: every point of the face, its tolerance
included, in the face’s placement. None where face is not a face
of this model or no box has been kept for it yet; a kept box is
found by ogeom_algo::face_bounds, and by the operations that read
face boxes, and is kept until the face, its wires, edges or vertices,
or the geometry in place change.
The box is kept in the face’s own frame. Under a placement that turns the face off the axes it is the box of the turned box, which holds the face but stands clear of it.
Sourcepub fn kept_face_box(
&self,
face: &Shape,
find: impl FnOnce(&Shape) -> OgeomResult<Aabb>,
) -> OgeomResult<Aabb>
pub fn kept_face_box( &self, face: &Shape, find: impl FnOnce(&Shape) -> OgeomResult<Aabb>, ) -> OgeomResult<Aabb>
The box kept for a face in its own frame, without its placement or
its tolerance; where none is kept, find is asked for it with the
face unplaced, and its answer is kept.
find must hold every point of the face it is given, and is what
Model::face_bounds reports from then on. Where the face cannot
keep a box (the geometry is being rewritten), find’s answer is
returned and not kept.
§Errors
OgeomError::Construction
if face is not a face of this model; as find reports.
Sourcepub fn kept_read<T: Any + Send + Sync>(
&self,
shape: &Shape,
same: impl Fn(&T) -> bool,
read: impl FnOnce() -> OgeomResult<(T, bool)>,
) -> OgeomResult<Arc<T>>
pub fn kept_read<T: Any + Send + Sync>( &self, shape: &Shape, same: impl Fn(&T) -> bool, read: impl FnOnce() -> OgeomResult<(T, bool)>, ) -> OgeomResult<Arc<T>>
What read finds of shape, kept beside the model and handed out
again until anything it was read from changes.
A read of type T kept for shape that same accepts is returned
as it is; otherwise read is asked, and its answer kept where it
says to keep it. read must depend only on what lies below shape
(the nodes’ data and children, the geometry and placements they
name, the face boxes kept), and same must accept only a read made
with the inputs the caller would give read now.
What is kept for a shape is forgotten when a node below it is
changed (Model::node_mut, Model::widen growing a tolerance,
Model::undo_widened, Model::unshare repointing a child),
when a surface or a pcurve is rewritten in place, and when
Model::retain_reachable drops the shape. A few shapes keep their
reads at once, the oldest forgotten first. Keeping walks every node
below the shape once, so it pays for a read that costs more than
that walk.
§Errors
As read reports.
Sourcepub fn kept_reads<T: Any + Send + Sync>(
&self,
same: impl Fn(&T) -> bool,
) -> Vec<Arc<T>>
pub fn kept_reads<T: Any + Send + Sync>( &self, same: impl Fn(&T) -> bool, ) -> Vec<Arc<T>>
Every read of type T kept now, for any shape, that same
accepts, the shape kept latest first: what Model::kept_read
would hand back for its shape. Each was read from its shape’s nodes
as they stand, so a part of one that depends only on the nodes below
a face holds for that face in any shape holding it.
Sourcepub fn kind_of(&self, shape: &Shape) -> OgeomResult<ShapeType>
pub fn kind_of(&self, shape: &Shape) -> OgeomResult<ShapeType>
What kind of shape this is.
§Errors
OgeomError::Dangling if the handle does not
resolve in this model.
Sourcepub fn tolerance_of(&self, shape: &Shape) -> OgeomResult<Option<Tolerance>>
pub fn tolerance_of(&self, shape: &Shape) -> OgeomResult<Option<Tolerance>>
Sourcepub fn node_count(&self) -> usize
pub fn node_count(&self) -> usize
Number of topology nodes.
Sourcepub fn nodes(&self) -> impl Iterator<Item = (TShapeId, &TShape)>
pub fn nodes(&self) -> impl Iterator<Item = (TShapeId, &TShape)>
Every topology node, with its handle, in arena order.
For writing a document out. Traversal from a root shape reaches only what that root bounds; a document is everything in it.
Sourcepub fn identities(&self) -> impl Iterator<Item = (TShapeId, EntityId)>
pub fn identities(&self) -> impl Iterator<Item = (TShapeId, EntityId)>
Every node that has been given an identity, with it.
Sourcepub fn add_vertex(&mut self, data: VertexData) -> Shape
pub fn add_vertex(&mut self, data: VertexData) -> Shape
Add a vertex.
Sourcepub fn add_point(&mut self, point: Point) -> Shape
pub fn add_point(&mut self, point: Point) -> Shape
Add a vertex at point with the minimum tolerance.
Sourcepub fn add_edge(
&mut self,
data: EdgeData,
bounds: &[Shape],
) -> OgeomResult<Shape>
pub fn add_edge( &mut self, data: EdgeData, bounds: &[Shape], ) -> OgeomResult<Shape>
Add an edge bounded by the given vertices.
The vertices are the edge’s ends, in order. A closed edge (a full circle) names the same vertex twice rather than once, so that walking its boundary yields a start and an end as every other edge does.
§Errors
OgeomError::Construction if a bound is
not a vertex, or if there are more than two;
OgeomError::Invariant if a vertex’s
tolerance is tighter than the edge’s, breaking the containment rule.
Sourcepub fn add_wire(&mut self, edges: &[Shape]) -> OgeomResult<Shape>
pub fn add_wire(&mut self, edges: &[Shape]) -> OgeomResult<Shape>
Add a wire from a sequence of edges.
§Errors
OgeomError::Construction if a child is
not an edge, or the wire is empty.
Sourcepub fn add_face(
&mut self,
data: FaceData,
wires: &[Shape],
) -> OgeomResult<Shape>
pub fn add_face( &mut self, data: FaceData, wires: &[Shape], ) -> OgeomResult<Shape>
Add a face bounded by the given wires.
The first wire is the outer boundary and any others are holes, and
the face keeps them in that order whichever way it is later used; see
Model::outer_wire.
A face with no wires covers its surface’s whole domain, and is recorded as naturally restricted.
§Errors
OgeomError::Construction if a bound is
not a wire; OgeomError::Invariant if the
containment rule is broken.
Sourcepub fn rechart_face(
&mut self,
face: &Shape,
surface: SurfaceId,
wires: &[Shape],
) -> OgeomResult<()>
pub fn rechart_face( &mut self, face: &Shape, surface: SurfaceId, wires: &[Shape], ) -> OgeomResult<()>
Restate face in place on surface, bounded by wires: the same
face read on another chart of the same points, held by every shape
that held it. For a builder that has re-charted a face (a sphere
face turned so its poles stand clear of its trim) and whose shells,
documents and tables already name the face: none of them has to
learn a new one.
The face’s kept triangulation and box are forgotten, as is what is kept of every shape holding it.
§Errors
OgeomError::Construction
if face is not a face, a wire is not a wire, or wires is empty;
OgeomError::Dangling if face
is not in this model.
Sourcepub fn add_shell(&mut self, faces: &[Shape]) -> OgeomResult<Shape>
pub fn add_shell(&mut self, faces: &[Shape]) -> OgeomResult<Shape>
Add a shell from a set of faces.
§Errors
OgeomError::Construction if a child is
not a face, or the shell is empty.
Sourcepub fn add_solid(&mut self, shells: &[Shape]) -> OgeomResult<Shape>
pub fn add_solid(&mut self, shells: &[Shape]) -> OgeomResult<Shape>
Add a solid bounded by the given shells.
§Errors
OgeomError::Construction if a child is
not a shell, or the solid is empty.
Sourcepub fn add_compsolid(&mut self, solids: &[Shape]) -> OgeomResult<Shape>
pub fn add_compsolid(&mut self, solids: &[Shape]) -> OgeomResult<Shape>
Add a compsolid from solids sharing faces.
§Errors
OgeomError::Construction if a child is
not a solid, or it is empty.
Sourcepub fn add_compound(&mut self, shapes: &[Shape]) -> OgeomResult<Shape>
pub fn add_compound(&mut self, shapes: &[Shape]) -> OgeomResult<Shape>
Add a compound of arbitrary shapes.
The one container with no type constraint; that is what a compound is for. It may be empty, since an empty result is a legitimate answer from a boolean and needs somewhere to live.
§Errors
OgeomError::Dangling if a child does not
resolve in this model.
Sourcepub fn children_of(&self, shape: &Shape) -> OgeomResult<Vec<Shape>>
pub fn children_of(&self, shape: &Shape) -> OgeomResult<Vec<Shape>>
The direct children of a shape, with this shape’s placement and orientation composed onto each.
The reason traversal is correct by default rather than by discipline: a child’s placement in the world is its parent’s composed with its own, and its orientation is its parent’s composed with its own. Returning raw children would leave every caller to remember both, and the failure is silent: face normals that flip inconsistently, sub-shapes drawn at the origin.
§Errors
OgeomError::Dangling if the shape does not
resolve in this model.
Sourcepub fn ordered_children_of(&self, shape: &Shape) -> OgeomResult<Vec<Shape>>
pub fn ordered_children_of(&self, shape: &Shape) -> OgeomResult<Vec<Shape>>
A shape’s children in traversal order.
The same shapes as Model::children_of, but with the list reversed
when the parent is reversed. Order carries meaning for a wire (its
edges run head to tail), and reversing a wire has to reverse the walk as
well as each edge, or consecutive edges stop sharing a vertex and the
boundary comes apart. For a shell or a solid the order means nothing and
the reversal is invisible.
Model::children_of stays the raw accessor: it returns what is
stored, which is what a rebuild or a comparison wants.
A reversed face’s wires come back reversed too, so its holes are
listed before its outer wire. A face stores its outer wire first, and
that is the only place the order means anything: code that wants the
outer wire asks Model::outer_wire, and code that wants every wire
walked under the face’s sense, outer first, asks
Model::children_of, whose wires carry the face’s orientation in
stored order.
§Errors
OgeomError::Dangling if the shape does not
resolve in this model.
Sourcepub fn outer_wire(&self, face: &Shape) -> OgeomResult<Option<Shape>>
pub fn outer_wire(&self, face: &Shape) -> OgeomResult<Option<Shape>>
A face’s outer wire, carrying the face’s placement and orientation,
or None for a face with no wires (one covering its whole surface).
The outer wire is the first one the face stores, whichever way the
face is used. Model::ordered_children_of on a reversed face lists
the holes first, so its first wire is not this one.
§Errors
OgeomError::Dangling if the face does not
resolve in this model; OgeomError::Construction
if the shape is not a face.
Sourcepub fn widen(&mut self, shape: &Shape, to: Tolerance) -> OgeomResult<()>
pub fn widen(&mut self, shape: &Shape, to: Tolerance) -> OgeomResult<()>
Widen a shape’s tolerance, and every sub-shape’s with it.
The cascade is the point. The containment rule is transitive: a face’s edges must be no tighter than the face, and those edges’ vertices no tighter than the edges. Widening only one level leaves the rule broken two levels down, where nothing will notice until a containment test quietly answers about geometry that does not meet.
Tolerances only ever grow, so this is the sanctioned repair: raise what bounds, never lower what is bounded.
The nodes are widened where they stand, held by other shapes as well
or not (Model::note_held): a boolean widens a vertex its rebuilt
edges end on though a face it set aside, and so the operand, holds
it too. Only a tolerance grows: every shape holding the node keeps
its geometry and its pcurves, and a looser bound still bounds what
it bounded, so each stays valid. An editor starting from a shape it
was given copies what is held first (Model::unshare), and widens
no other shape.
§Errors
OgeomError::Dangling if the shape, or
anything below it, does not resolve in this model.
Sourcepub fn note_widened(&mut self) -> WidenMark
pub fn note_widened(&mut self) -> WidenMark
Start noting the tolerances Model::widen grows and edits through
Model::node_mut may grow, so an attempt that fails can put them
back with Model::undo_widened. Where a journal is
open already, it goes on and the mark is where this attempt began.
Sourcepub fn undo_widened(&mut self, mark: WidenMark)
pub fn undo_widened(&mut self, mark: WidenMark)
Put back every tolerance noted since mark, and
close the journal where mark opened it.
Sourcepub fn keep_widened(&mut self, mark: WidenMark)
pub fn keep_widened(&mut self, mark: WidenMark)
Keep the tolerances noted since mark as they now stand, and close
the journal where mark opened it.
Sourcepub fn note_held(&mut self, result: &Shape, since: usize) -> OgeomResult<()>
pub fn note_held(&mut self, result: &Shape, since: usize) -> OgeomResult<()>
Record that result holds nodes made before the model held since
nodes: what an operation passed through into its result from the
shapes it was given, which those shapes still hold.
The walk goes down from result through the nodes made since, and
marks each older node where it first meets one; what lies below a
marked node is held with it. It costs what the operation made.
Model::unshare reads the marks.
§Errors
OgeomError::Dangling if the
shape, or anything below it, does not resolve in this model.
Make every node below root the root’s alone, so that an edit in
place below it changes no other shape.
Each node an operation passed through into root from the shapes
it was given (Model::note_held), and everything below it, is
copied: the same kind, data and identity, and the same kept face
box. The nodes root holds alone that held one now hold its copy,
at the same placement and orientation. What is held is found from
root down; a root that is itself held is left as it stands,
with everything below it.
Returns each node copied, with its copy, in the order copied.
§Errors
OgeomError::Dangling if the
shape, or anything below it, does not resolve in this model.
As Model::unshare for several shapes at once, for an operation
that takes shapes and returns what it makes of them, and leaves the
shapes it was given as they are.
Nothing given is edited: each node held below a shape, and each
node on the way down to one, the shape itself included, is copied
once for them all, so a shape with anything held below it comes
back as a copy. What a copy shares with the shape it was copied
from is noted as held by both (Model::note_held).
§Errors
As Model::unshare.
Sourcepub fn check_tolerances(&self, root: &Shape) -> OgeomResult<()>
pub fn check_tolerances(&self, root: &Shape) -> OgeomResult<()>
Verify the containment rule across a whole shape tree.
docs/DATA_MODEL.md §5. Walks parent to child and checks that whatever
bounds is no tighter than what it bounds.
§Errors
OgeomError::Invariant at the first
violation, naming the two shape types involved.
Sourcepub fn same_position(
&self,
a: &Shape,
b: &Shape,
tol: Tolerances,
) -> OgeomResult<bool>
pub fn same_position( &self, a: &Shape, b: &Shape, tol: Tolerances, ) -> OgeomResult<bool>
Whether two shapes coincide in position, comparing composed transforms.
§Errors
Sourcepub fn placed(&mut self, shape: &Shape, transform: Transform) -> Shape
pub fn placed(&mut self, shape: &Shape, transform: Transform) -> Shape
A shape placed by an additional transform.
Interns the transform and composes it onto the shape’s placement, so the underlying node (and all its geometry) is shared rather than copied. Placing ten thousand instances of a part costs ten thousand short chains and one copy of the geometry.
Records no history: nothing is built, and a sub-shape s of the
input stands in the result as s.moved(by), where by is the
result’s location with the input’s own taken off,
result.location().then(&shape.location().inverted()). A caller that
traces names across the move, or composes it with an operation’s
history, places with ogeom_algo::transformed, which makes the same
placement and records every sub-shape into its occurrence.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Model
impl RefUnwindSafe for Model
impl Send for Model
impl Sync for Model
impl Unpin for Model
impl UnsafeUnpin for Model
impl UnwindSafe for Model
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read more§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.