ifcSpace Update
build and deploy Speckle functions / publish-automate-function-version (push) Has been cancelled
build and deploy Speckle functions / publish-automate-function-version (push) Has been cancelled
This commit is contained in:
@@ -14,7 +14,7 @@ from utils.type_manager import TypeManager
|
||||
|
||||
SPATIAL_STRUCTURE_TYPES = {
|
||||
"IfcBuilding", "IfcBuildingStorey",
|
||||
"IfcSpace", "IfcExternalSpatialElement", "IfcSpatialZone",
|
||||
"IfcExternalSpatialElement", "IfcSpatialZone",
|
||||
"IfcGrid", "IfcAnnotation",
|
||||
}
|
||||
|
||||
@@ -110,7 +110,12 @@ def automate_function(
|
||||
skipped_spatial += 1
|
||||
continue
|
||||
|
||||
name = build_element_name(obj)
|
||||
# IfcSpace uses the Speckle object name (e.g. "Rooms - Live/Work Unit 507")
|
||||
# instead of Family:Type (which is "none:none" for Revit rooms)
|
||||
if ifc_class == "IfcSpace":
|
||||
name = getattr(obj, "name", None) or build_element_name(obj)
|
||||
else:
|
||||
name = build_element_name(obj)
|
||||
storey = storey_manager.get_or_create(level_name)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
@@ -250,8 +255,10 @@ def _create_element(ifc, ifc_class, name, rep, placement, storey,
|
||||
element.ObjectPlacement = _make_placement(ifc, 0.0, 0.0, 0.0)
|
||||
|
||||
# Queue spatial assignment (batched flush at end for performance)
|
||||
# IfcSpace is a spatial structure element — must be decomposed (aggregated)
|
||||
# under its IfcBuildingStorey, not spatially contained.
|
||||
if storey_manager:
|
||||
if ifc_class == "IfcSite":
|
||||
if ifc_class in ("IfcSite", "IfcSpace"):
|
||||
storey_manager.queue_aggregate(storey, element)
|
||||
else:
|
||||
storey_manager.queue_contain(storey, element)
|
||||
|
||||
@@ -424,9 +424,104 @@ def write_common_pset(ifc, element, obj: Base, ifc_class: str, category_name: st
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# IfcSpace-specific: set Name, LongName, Category, and BaseQuantities
|
||||
if ifc_class == "IfcSpace":
|
||||
_write_space_properties(ifc, element, obj, ifc_props)
|
||||
|
||||
_write_pset(ifc, element, pset_name, ifc_props)
|
||||
|
||||
|
||||
def _write_space_properties(ifc, element, obj: Base, ifc_props: list):
|
||||
"""
|
||||
Set IfcSpace attributes and BaseQuantities from Revit Room parameters.
|
||||
|
||||
Uses internalDefinitionName to find values:
|
||||
ROOM_NUMBER → IfcSpace.Name + Pset_SpaceCommon.Reference
|
||||
ROOM_NAME → IfcSpace.LongName
|
||||
Occupant → Pset_SpaceCommon.Category
|
||||
ROOM_AREA → Qto_SpaceBaseQuantities.NetFloorArea
|
||||
ROOM_VOLUME → Qto_SpaceBaseQuantities.NetVolume
|
||||
"""
|
||||
props = _get_props_dict(obj)
|
||||
params = _safe_get(props, "Parameters", {})
|
||||
inst_params = _safe_get(params, "Instance Parameters", {})
|
||||
|
||||
# --- Room Number → IfcSpace.Name + Pset_SpaceCommon.Reference ---
|
||||
room_number = _param_value(inst_params, "ROOM_NUMBER")
|
||||
if room_number:
|
||||
room_number = str(room_number).strip()
|
||||
element.Name = room_number
|
||||
# Replace any existing Reference in ifc_props
|
||||
ifc_props[:] = [p for p in ifc_props if p.Name != "Reference"]
|
||||
p = _make_prop(ifc, "Reference", "IfcIdentifier", room_number)
|
||||
if p:
|
||||
ifc_props.append(p)
|
||||
# Also add as explicit RoomNumber in the pset
|
||||
p = _make_prop(ifc, "RoomNumber", "IfcLabel", room_number)
|
||||
if p:
|
||||
ifc_props.append(p)
|
||||
|
||||
# --- Room Name → IfcSpace.LongName + Pset_SpaceCommon.RoomName ---
|
||||
room_name = _param_value(inst_params, "ROOM_NAME")
|
||||
if not room_name:
|
||||
# Fallback to the Speckle object's own name
|
||||
room_name = getattr(obj, "name", None)
|
||||
if room_name:
|
||||
room_name = str(room_name).strip()
|
||||
try:
|
||||
element.LongName = room_name
|
||||
except AttributeError:
|
||||
pass
|
||||
p = _make_prop(ifc, "RoomName", "IfcLabel", room_name)
|
||||
if p:
|
||||
ifc_props.append(p)
|
||||
|
||||
# --- Occupant → Pset_SpaceCommon.Category ---
|
||||
occupant = _param_value(inst_params, "Occupant")
|
||||
if occupant:
|
||||
p = _make_prop(ifc, "Category", "IfcLabel", str(occupant).strip())
|
||||
if p:
|
||||
ifc_props.append(p)
|
||||
|
||||
# --- Area & Volume → Qto_SpaceBaseQuantities ---
|
||||
quantities = []
|
||||
|
||||
area_val = _param_value(inst_params, "ROOM_AREA")
|
||||
if area_val is not None:
|
||||
try:
|
||||
q = ifc.create_entity(
|
||||
"IfcQuantityArea",
|
||||
Name="NetFloorArea",
|
||||
AreaValue=float(area_val),
|
||||
)
|
||||
quantities.append(q)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
volume_val = _param_value(inst_params, "ROOM_VOLUME")
|
||||
if volume_val is not None:
|
||||
try:
|
||||
q = ifc.create_entity(
|
||||
"IfcQuantityVolume",
|
||||
Name="NetVolume",
|
||||
VolumeValue=float(volume_val),
|
||||
)
|
||||
quantities.append(q)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if quantities:
|
||||
try:
|
||||
qto = ifcopenshell.api.run(
|
||||
"pset.add_qto", ifc,
|
||||
product=element,
|
||||
name="Qto_SpaceBaseQuantities",
|
||||
)
|
||||
qto.Quantities = quantities
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Qto_SpaceBaseQuantities: {e}")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Pset_EnvironmentalImpactIndicators (always written, Reference = TypeName)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user