Skip to main content

Model

Struct Model 

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

A parsed IFC file: header, entities, and indices over them.

Implementations§

Source§

impl Model

Source

pub fn new() -> Self

An empty model.

Source

pub fn with_source(source: Arc<dyn EntitySource>) -> Self

An empty model whose entities a codec registers with Model::insert_lazy and source decodes on first access.

Source

pub fn header(&self) -> &Header

The file header (schema declaration, description, author).

Source

pub fn header_mut(&mut self) -> &mut Header

Mutable access to the header, for writers and editors.

Source

pub fn diagnostics(&self) -> &[Diagnostic]

Non-fatal problems reported by the codec that read this model.

Empty for a clean file. A non-empty slice means the model is incomplete relative to its source: the codec recovered from damage and each entry says exactly what was dropped, so a consumer can surface “loaded, 1 record skipped” instead of pretending the read was lossless.

Source

pub fn is_complete(&self) -> bool

Whether the read that produced this model dropped anything.

Source

pub fn push_diagnostic(&mut self, diagnostic: Diagnostic)

Attaches a codec diagnostic. Called by codecs during a recovered read.

Source

pub fn insert(&mut self, id: EntityId, entity: Entity)

Insert an entity under a specific id, replacing any previous occupant.

Codecs use this to preserve file ids exactly.

Source

pub fn insert_lazy(&mut self, id: EntityId, type_name: &str, span: Range<usize>)

Register the entity stored at span of this model’s source under id, without decoding it; it is decoded on first access. Replaces any previous occupant exactly as Model::insert does.

type_name must be the type the span decodes to, which lets Model::ids_of_type answer without decoding. Only a codec that validated the span may register it (see EntitySource).

§Panics

When the model has no source (Model::with_source).

Source

pub fn reserve(&mut self, additional: usize)

Reserve room for additional more entities; a codec that knows the record count up front avoids regrowing the storage while it loads.

Source

pub fn push(&mut self, entity: Entity) -> EntityId

Append an entity, allocating the next free id.

Source

pub fn revision(&self) -> u64

How many structural changes this model has seen.

Starts at zero and increases; the absolute value carries no meaning beyond comparison. See Transaction.

Source

pub fn next_id(&self) -> EntityId

The id Model::push would allocate next.

A transaction reserves ids from here so several creates in one batch cannot collide with each other or with existing entities.

Source

pub fn get(&self, id: EntityId) -> Option<&Entity>

Look up one entity, decoding it first if it was loaded lazily.

Source

pub fn contains(&self, id: EntityId) -> bool

Whether id names an entity, without decoding it.

Source

pub fn decoded_len(&self) -> usize

How many entities have been decoded. Equals Model::len for a model built from decoded entities; for a lazily loaded one it counts the entities accessed so far.

Source

pub fn decode_all(&self, threads: usize)

Decode every entity now, on up to threads threads.

A lazily loaded model decodes on first access, one entity at a time. A consumer about to touch most of the model – a writer, a full validation, a geometry pass – can decode everything up front in parallel instead. Idempotent, and a no-op on a decoded model.

Source

pub fn len(&self) -> usize

Number of entities.

Source

pub fn is_empty(&self) -> bool

Whether the model holds no entities.

Source

pub fn ids(&self) -> impl Iterator<Item = EntityId> + '_

Entity ids in original file order.

Source

pub fn iter(&self) -> impl Iterator<Item = (EntityId, &Entity)> + '_

Entities in original file order.

Source

pub fn ids_of_type(&self, type_name: &str) -> &[EntityId]

Ids of every entity with this exact type name, case-insensitive.

This is an exact-type query and does not include subtypes: asking for IfcElement will not return walls. Subtype queries need the schema, which this crate does not depend on. The facade’s ifc::ids_of_type_including_subtypes (feature schema) joins the two.

Source

pub fn of_type<'a>( &'a self, type_name: &str, ) -> impl Iterator<Item = (EntityId, &'a Entity)>

Entities with this exact type name.

Source

pub fn type_histogram(&self) -> Vec<(&str, usize)>

Every distinct type name present, with its instance count.

Useful as a cheap file summary and as the basis for a coverage report of what a given build can and cannot interpret.

Source

pub fn dangling_references(&self) -> Vec<(EntityId, EntityId)>

Ids that are referenced by some entity but do not exist.

A dangling reference is the most common corruption in real files, and it is a structural question, so it belongs here rather than in a validation crate.

Source§

impl Model

Source

pub fn set_attribute( &mut self, id: EntityId, index: usize, value: Value, ) -> Option<Value>

Set one positional attribute on an existing entity.

Returns the value previously at that slot, or None if id does not name an entity in this model. Growing past the entity’s current attribute count pads with Value::Null, matching how STEP itself treats a missing trailing optional attribute.

Does not touch type_name, so the by-type index stays correct without needing to run the same reindex logic Model::insert does. Renaming an entity’s type is a structural change, not an attribute edit: use Model::retype.

use ifc_model::{Entity, EntityId, Model, Value};

let mut model = Model::new();
let id = model.push(Entity::new("IFCCARTESIANPOINT", vec![Value::List(vec![
    Value::Real(0.0), Value::Real(0.0),
])]));

let previous = model.set_attribute(id, 0, Value::List(vec![
    Value::Real(10.0), Value::Real(20.0),
]));
assert!(previous.is_some());
let coords = model.get(id).unwrap().attribute(0).unwrap().as_list().unwrap();
assert_eq!(coords[0].as_f64(), Some(10.0));
Source

pub fn set_attributes( &mut self, id: EntityId, edits: impl IntoIterator<Item = (usize, Value)>, ) -> Option<Vec<Value>>

Apply several attribute edits to one entity as a single unit.

edits are applied in order; a later edit to the same slot wins. This exists because a caller updating several attributes wants to do it in one lookup rather than repeating Model::set_attribute’s entity lookup per field — the practical difference for callers is that this is one indexmap probe instead of N, not a transactional guarantee (there is nothing to roll back: slot writes cannot themselves fail).

Returns the previous values in edits order, or None if id does not name an entity.

Source

pub fn retype( &mut self, id: EntityId, type_name: impl Into<Arc<str>>, ) -> Option<Arc<str>>

Change an entity’s type in place, keeping its id and attributes.

Reindexes by_type so ids_of_type reflects the new type immediately – the operation Model::insert already performs when an id is reused with a different type, exposed here without requiring the caller to reconstruct the whole entity.

Returns the previous type name, or None if id does not name an entity.

Source

pub fn remove(&mut self, id: EntityId) -> Option<Entity>

Remove an entity entirely.

Returns the removed entity, or None if id was not present. Leaves every reference to id from other entities dangling – detect those with Model::dangling_references after a batch of removals, the same way a codec would detect them in a hand-edited file.

Trait Implementations§

Source§

impl Clone for Model

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Model

Source§

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

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

impl Default for Model

Source§

fn default() -> Self

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

Auto Trait Implementations§

§

impl !RefUnwindSafe for Model

§

impl !UnwindSafe for Model

§

impl Freeze for Model

§

impl Send for Model

§

impl Sync for Model

§

impl Unpin for Model

§

impl UnsafeUnpin for Model

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.