use ifc_model::guid::Guid;
use ifc_model::{EntityId, Model, Transaction, Value};
use super::external::{check_external, EXTERNAL};
use super::owned_relationships::{refs, relate_owned};
use super::release::stage;
use super::{
container, invalid, optional_text, ExternalSpatialDraft, ProjectLibraryDraft,
SpatialAuthoringResult, SpatialDraft,
};
use crate::relation::slots::{AGGREGATES, CONTAINED_IN};
use crate::tree::SpatialKind;
pub fn create_spatial_element_with_owner_history(
tx: &mut Transaction,
model: &Model,
kind: SpatialKind,
global_id: &str,
draft: SpatialDraft<'_>,
owner_history: EntityId,
) -> SpatialAuthoringResult<EntityId> {
let (type_name, _) = container(kind, global_id)?;
let values = vec![
("GlobalId", Value::Text(global_id.into())),
("Name", optional_text(draft.name)),
("Description", optional_text(draft.description)),
(
"ObjectPlacement",
draft.placement.map_or(Value::Null, Value::Ref),
),
("LongName", optional_text(draft.long_name)),
(
"CompositionType",
draft
.composition
.map_or(Value::Null, |t| Value::Enum(t.into())),
),
];
stage(tx, model, type_name, values, Some(owner_history))
}
pub fn create_project_with_owner_history(
tx: &mut Transaction,
model: &Model,
global_id: &str,
name: Option<&str>,
units: Option<EntityId>,
owner_history: EntityId,
) -> SpatialAuthoringResult<EntityId> {
const ENTITY: &str = "IFCPROJECT";
if Guid::parse(global_id).is_none() {
return Err(invalid(ENTITY, "GlobalId", global_id));
}
let values = vec![
("GlobalId", Value::Text(global_id.into())),
("Name", optional_text(name)),
("UnitsInContext", units.map_or(Value::Null, Value::Ref)),
];
stage(tx, model, ENTITY, values, Some(owner_history))
}
pub fn aggregate_with_owner_history(
tx: &mut Transaction,
model: &Model,
global_id: &str,
parent: EntityId,
children: &[EntityId],
owner_history: EntityId,
) -> SpatialAuthoringResult<EntityId> {
let extra = Vec::new();
relate_owned(
tx,
model,
AGGREGATES,
global_id,
parent,
children,
extra,
owner_history,
)
}
pub fn contain_with_owner_history(
tx: &mut Transaction,
model: &Model,
global_id: &str,
structure: EntityId,
elements: &[EntityId],
owner_history: EntityId,
) -> SpatialAuthoringResult<EntityId> {
let extra = Vec::new();
relate_owned(
tx,
model,
CONTAINED_IN,
global_id,
structure,
elements,
extra,
owner_history,
)
}
pub fn create_external_spatial_element_with_owner_history(
tx: &mut Transaction,
model: &Model,
global_id: &str,
draft: ExternalSpatialDraft<'_>,
owner_history: EntityId,
) -> SpatialAuthoringResult<EntityId> {
check_external(global_id, &draft)?;
let values = vec![
("GlobalId", Value::Text(global_id.into())),
("Name", optional_text(draft.name)),
("Description", optional_text(draft.description)),
("ObjectType", optional_text(draft.object_type)),
(
"ObjectPlacement",
draft.placement.map_or(Value::Null, Value::Ref),
),
(
"Representation",
draft.representation.map_or(Value::Null, Value::Ref),
),
("LongName", optional_text(draft.long_name)),
(
"PredefinedType",
draft
.predefined_type
.map_or(Value::Null, |t| Value::Enum(t.into())),
),
];
stage(tx, model, EXTERNAL, values, Some(owner_history))
}
pub fn create_project_library_with_owner_history(
tx: &mut Transaction,
model: &Model,
global_id: &str,
draft: ProjectLibraryDraft<'_>,
representation_contexts: &[EntityId],
owner_history: EntityId,
) -> SpatialAuthoringResult<EntityId> {
const ENTITY: &str = "IFCPROJECTLIBRARY";
if Guid::parse(global_id).is_none() {
return Err(invalid(ENTITY, "GlobalId", global_id));
}
let contexts = if representation_contexts.is_empty() {
Value::Null
} else {
refs(representation_contexts)
};
let values = vec![
("GlobalId", Value::Text(global_id.into())),
("Name", optional_text(draft.name)),
("Description", optional_text(draft.description)),
("ObjectType", optional_text(draft.object_type)),
("LongName", optional_text(draft.long_name)),
("Phase", optional_text(draft.phase)),
("RepresentationContexts", contexts),
(
"UnitsInContext",
draft.units.map_or(Value::Null, Value::Ref),
),
];
stage(tx, model, ENTITY, values, Some(owner_history))
}