pub mod boundary;
mod index;
pub(crate) mod link;
pub(crate) mod slots;
pub use boundary::{
BoundaryExposure, BoundaryPhysicality, ConnectionGeometryAnomaly, SpaceBoundary,
};
pub use index::RelationshipIndex;
pub use link::{Relationship, RelationshipKind};
use ifc_model::{EntityId, Model};
#[must_use]
pub fn all(model: &Model) -> Vec<Relationship> {
let mut out = Vec::new();
for (slots, kind) in [
(slots::AGGREGATES, RelationshipKind::Aggregates),
(slots::CONTAINED_IN, RelationshipKind::ContainedIn),
(slots::NESTS, RelationshipKind::Nests),
(slots::COVERS_ELEMENTS, RelationshipKind::CoversElements),
(slots::COVERS_SPACES, RelationshipKind::CoversSpaces),
(
slots::INTERFERES_ELEMENTS,
RelationshipKind::InterferesElements,
),
(slots::ASSIGNS_TO_ACTOR, RelationshipKind::AssignsToActor),
(
slots::ASSIGNS_TO_PROCESS,
RelationshipKind::AssignsToProcess,
),
(
slots::ASSIGNS_TO_PRODUCT,
RelationshipKind::AssignsToProduct,
),
(
slots::ASSIGNS_TO_GROUP_BY_FACTOR,
RelationshipKind::AssignsToGroupByFactor,
),
(slots::DECLARES, RelationshipKind::Declares),
(slots::DEFINES_BY_OBJECT, RelationshipKind::DefinesByObject),
(
slots::FLOW_CONTROL_ELEMENTS,
RelationshipKind::FlowControlElements,
),
(
slots::SERVICES_BUILDINGS,
RelationshipKind::ServicesBuildings,
),
(
slots::CONNECTS_WITH_ECCENTRICITY,
RelationshipKind::ConnectsWithEccentricity,
),
] {
for id in model.ids_of_type(slots.type_name) {
if let Some(relationship) = link::read(model, *id, slots, kind) {
out.push(relationship);
}
}
}
for slots in slots::CONNECTS_ELEMENT_TYPES {
for id in model.ids_of_type(slots.type_name) {
if let Some(relationship) =
link::read(model, *id, slots, RelationshipKind::ConnectsElements)
{
out.push(relationship);
}
}
}
out
}
#[must_use]
pub fn naming(model: &Model, target: EntityId) -> Vec<Relationship> {
all(model)
.into_iter()
.filter(|relationship| relationship.related.contains(&target))
.collect()
}