openbim-ifc 0.8.1

Facade for the openBIM IFC crates: pick codecs and domains as features.
Documentation
//! `ifc` — the facade. Pick your codecs and domains as cargo features.
//!
//! # The shape of the library
//!
//! ```text
//!   codecs                 model                  domain views
//!   ---------------        ---------------        ------------------
//!   ifc-step      \                        /      ifc-cost
//!   ifc-xml        >----->  ifc-model  <--<       ifc-schedule
//!   (ifc-json)    /         (entities)     \      ifc-properties, ...
//! ```
//!
//! Two separations hold this together, and both are enforced by tests rather
//! than convention:
//!
//! **1. The model knows no domain semantics.** [`Model`] stores
//! `(id, type_name, attributes)` and nothing else. It has never heard of a
//! cost item. Domain crates are *views* that borrow a `&Model` and interpret
//! it, so a build without them still reads and writes their data untouched.
//!
//! **2. The model knows no serialization.** [`Codec`] is a trait *in the model
//! crate*; `ifc-step` and `ifc-xml` implement it. IFC-JSON would be a third
//! implementation, requiring no change to the model.
//!
//! # Choosing features
//!
//! | Feature | Pulls in | For |
//! | --- | --- | --- |
//! | `step` *(default)* | `ifc-step` | Reading `.ifc` files |
//! | `ifcxml` | `ifc-xml` | Reading/writing `.ifcxml` |
//! | `schema` | `ifc-schema` | Subtype queries, conformant XML names |
//! | `material-templates` | `ifc-material` + template catalog | Material PSD applicability |
//! | `cost`, `schedule`, ... | one domain crate each | Interpreting that domain |
//! | `codecs` | both codecs | |
//! | `domains` | every domain view | |
//! | `full` | everything | |
//!
//! A thin viewer takes `default-features = false, features = ["step"]` and
//! compiles no domain code and no geometry stack, while still round-tripping
//! every entity in the file.
//!
//! ```
//! # #[cfg(feature = "step")] {
//! use ifc::{Codec, StepCodec};
//!
//! let source = b"ISO-10303-21;\nHEADER;\nFILE_DESCRIPTION((''),'2;1');\n\
//!                FILE_NAME('t.ifc','',( ''),(''),'','','');\n\
//!                FILE_SCHEMA(('IFC4'));\nENDSEC;\nDATA;\n\
//!                #1= IFCCOSTITEM('guid',$,'Excavation',$,$,$,$);\n\
//!                ENDSEC;\nEND-ISO-10303-21;\n";
//!
//! let model = StepCodec.read_bytes(source).unwrap();
//! assert_eq!(model.len(), 1);
//!
//! // The cost entity is present and re-exportable with no `cost` feature on.
//! let out = StepCodec.write_bytes(&model).unwrap();
//! assert!(String::from_utf8_lossy(&out).contains("IFCCOSTITEM"));
//! # }
//! ```

// The model is always available: it is the common vocabulary.
pub use ifc_model::{codec, Codec, Entity, EntityId, Header, Model, ModelError, Value};
// `EntityEditor::stage` and the domain writers take a transaction; without
// these a facade user could build an editor but never apply it.
pub use ifc_model::{Applied, Conflict, Transaction};

/// The STEP physical file codec (`.ifc`).
#[cfg(feature = "step")]
pub use ifc_step::StepCodec;

/// A STEP reader with an explicit policy: recovery, eager decoding, or a
/// memory-mapped read ([`StepReader::read_path_mapped`]).
#[cfg(feature = "step")]
pub use ifc_step::{OnMalformed, ParseOptions, StepReader};

/// The ifcXML codec (`.ifcxml`).
#[cfg(feature = "ifcxml")]
pub use ifc_xml::{XmlCodec, XmlProfile};

/// The IFC schema as queryable data.
#[cfg(feature = "schema")]
pub use ifc_schema::{Schema, SchemaVersion};

/// The whole schema crate, including the bundled schemas
/// (`schema::ifc4()`, `schema::for_version(..)`) that
/// [`ids_of_type_including_subtypes`] needs as input.
#[cfg(feature = "schema")]
pub use ifc_schema as schema;

// Needs the model's type index and the schema's subtype tree, which ADR 0003
// keeps in separate crates, so the join lives in this orchestration layer.
#[cfg(feature = "schema")]
mod subtype_query;
#[cfg(feature = "schema")]
pub use subtype_query::ids_of_type_including_subtypes;

/// Cost semantics as a borrowed view.
#[cfg(feature = "cost")]
pub use ifc_cost as cost;

/// Property sets and quantities.
#[cfg(feature = "properties")]
pub use ifc_properties as properties;

/// Versioned external PSD/QTO template catalogs and correction profiles.
#[cfg(feature = "property-catalog")]
pub use ifc_template_catalog as property_catalog;

/// Tasks, sequencing, calendars.
#[cfg(feature = "schedule")]
pub use ifc_schedule as schedule;

/// Material layer sets, profile sets, constituents.
#[cfg(feature = "material")]
pub use ifc_material as material;
#[cfg(feature = "material-templates")]
pub mod material_templates;

/// Classification, documents, libraries, and external-reference relationships.
#[cfg(feature = "classification")]
pub use ifc_classification as classification;

/// Approval resource semantics and approval associations.
#[cfg(feature = "approval")]
pub use ifc_approval as approval;

/// Permits, project orders, action requests, and performance history.
#[cfg(feature = "control")]
pub use ifc_control as control;

/// Tables and time series: value containers indexed by position or time.
#[cfg(feature = "tabular")]
pub use ifc_tabular as tabular;

/// Metrics, objectives, and constraint relationships.
#[cfg(feature = "constraint")]
pub use ifc_constraint as constraint;

/// Element, resource, and process type definitions.
#[cfg(feature = "element-type")]
pub use ifc_element_type as element_type;

/// Built element and distribution occurrence classes.
#[cfg(feature = "occurrence")]
pub use ifc_occurrence as occurrence;

/// Structural analysis model.
#[cfg(feature = "structural")]
pub use ifc_structural as structural;

/// Construction resources: actors, labour, equipment, crew, material,
/// product, subcontract, resource types, inventory, and usage quantities.
#[cfg(feature = "resource")]
pub use ifc_resource as resource;

/// Distribution systems and ports.
#[cfg(feature = "systems")]
pub use ifc_systems as systems;

/// Presentation styles.
#[cfg(feature = "style")]
pub use ifc_style as style;

/// Schema and integrity validation.
#[cfg(feature = "validate")]
pub use ifc_validate as validate;

/// Schema-checked construction and editing of entities.
#[cfg(feature = "author")]
pub use ifc_author as author;

/// Build or edit an entity by naming attributes rather than positioning them.
#[cfg(feature = "author")]
pub use ifc_author::{EntityBuilder, EntityEditor};

/// Containment and objectified relationship traversal.
#[cfg(feature = "spatial")]
pub use ifc_spatial as spatial;

/// The project/site/building/storey/element tree of a model.
#[cfg(feature = "spatial")]
pub use ifc_spatial::{SpatialKind, SpatialTree};

/// Representation selection and, with `geometry`, lowering to the DAG.
///
/// Available under `geometry-select` too: the module is the same, but a
/// select-only build compiles no geometry kernel and therefore exposes no
/// `lower` submodule.
#[cfg(feature = "geometry-select")]
pub use ifc_geometry as geometry;

/// Representation contexts and the selectors that choose 3D or 2D geometry.
///
/// Re-exported at the root because choosing what a drawing draws is a
/// first-class question, not an implementation detail of lowering.
#[cfg(feature = "geometry-select")]
pub use ifc_geometry::{
    all_contexts, context_of, plan_contexts, select_plan_representation,
    select_shape_representation, RepresentationContext, TargetView, PLAN_IDENTIFIERS,
    SOLID_IDENTIFIERS,
};

/// Where a product sits in the world.
///
/// Re-exported at the root, and available without the geometry kernel,
/// because every consumer needs world coordinates and a hand-rolled
/// `IfcLocalPlacement` walk is the most commonly botched code in an IFC
/// viewer: the composition order and the unit scaling are both easy to
/// invert.
#[cfg(feature = "geometry-select")]
pub use ifc_geometry::{product_world_transform, products_world_transforms};

/// How a product's body is modelled: its representation kind and, for swept
/// solids, the profile parameters, direction and depth in SI and world
/// coordinates.
///
/// Available without the geometry kernel, because a rule check asking "is
/// this beam an extrusion of an HEA300" reads parameters, not a mesh.
#[cfg(feature = "geometry-select")]
pub use ifc_geometry::{
    body_description, describe_profile, profile_outline, BodyDescription, BodyItem, BodyKind,
    ProfileDescription, ProfileOutline, ProfileParameters, SweepPath, SweptSolid,
};

/// Map conversion and coordinate reference systems.
#[cfg(feature = "georef")]
pub use ifc_georef as georef;

/// IFC4x3 alignment and linear placement.
#[cfg(feature = "alignment")]
pub use ifc_alignment as alignment;

// Answering "will a viewer draw this" needs containment AND representation
// contexts -- two sibling domain crates that ADR 0003 forbids from depending on
// each other, so the check lives in this orchestration layer.
#[cfg(all(feature = "spatial", feature = "geometry-select"))]
mod unreachable;
#[cfg(all(feature = "spatial", feature = "geometry-select"))]
pub use unreachable::{unreachable_products, Unreachable};

// A door's leaves and a window's panels need the product's placement AND its
// operation type and panel properties -- `ifc-geometry` and `ifc-properties`,
// siblings under ADR 0003 -- so the joins live in this orchestration layer
// (#148, #170). `operation` holds what the two share. Each of the three
// modules gates itself on `all(geometry-select, properties)` with an inner
// `#![cfg]`, so the declarations below compile to nothing without both.
mod door_operation;
mod operation;
mod window_operation;
#[cfg(all(feature = "geometry-select", feature = "properties"))]
pub use {
    door_operation::{
        door_operation, DoorOperation, DoorOperationError, DoorOperationType, Leaf, LeafMotion,
        PanelPosition, RefusedOperation,
    },
    operation::{Sector, Side},
    window_operation::{
        window_operation, RefusedWindowOperation, WindowOperation, WindowOperationError,
        WindowPanel, WindowPanelMotion, WindowPanelOperation, WindowPanelPosition,
        WindowPartitioning,
    },
};

// Each spatial container's elements with their exact properties (#121) joins
// `ifc-spatial` and `ifc-properties`, siblings under ADR 0003. The module
// gates itself on `all(spatial, properties)` with an inner `#![cfg]`.
mod spatial_properties;
#[cfg(all(feature = "spatial", feature = "properties"))]
pub use spatial_properties::{
    spatial_properties, ContainerElements, ContainerName, ElementMember, ElementProperties,
    SpatialContainer, SpatialMembership, SpatialProperties,
};

mod feature_report;
mod io;

pub use feature_report::compiled_features;
pub use io::{codecs, read_path};

#[cfg(feature = "step")]
pub use io::from_step_bytes;