Interior
Helpers for the interior models.
The one thing every interior user needs and does not have: a way to turn the FLAT mesh shape the rest of this SDK produces into the NESTED entity shape the interior models require.
client.buildings.get_area() returns AreaBuildings whose .buildings
is a Dict[str, DotBimMesh] — the flat {coordinates, indices} shape used
by the six outdoor grid models. Interior models need
{"geometry": {"payload": {"coordinates": …, "indices": …}}}. Passing the
flat form is not an error server-side: the entity is read as having no
geometry, skipped, and the analysis runs against an empty occluder, returning a
confident non-physical result.
So the natural thing to do — fetch neighbouring buildings and drop them into
context_geometry — is exactly the thing that silently produces a wrong
answer. These helpers exist so that path is one obvious call instead of a trap.
to_interior_entity
to_interior_entity(
mesh: Any,
*,
category: Optional[str] = None,
opening_factor: Optional[float] = None,
position: Optional[Mapping[str, float]] = None,
rotation: Optional[Mapping[str, float]] = None,
) -> Dict[str, Any]
Wrap a flat mesh in the nested interior entity shape.
Accepts a DotBimMesh, a plain {"coordinates": …, "indices": …}
dict, or an already-nested entity (returned with its extras applied), so it
is safe to call on anything.
Parameters mirror the wire contract rather than tidying it up:
category
Tags what an entity IS. Required by two of daylight-factor's four
tiers: the floors and buildings tiers cluster storeys from
barriers carrying category="floor" and then read their
geometry.position/rotation strictly — plain barriers give a
billed rejection, and categorised-but-untransformed slabs give a billed
500. The sensor_points and sensor_surfaces tiers ignore it.
opening_factor
daylight-factor only; emitted as openingFactor (camelCase, the only
spelling the worker reads). Visible-light transmittance in [0, 1].
position / rotation
Read strictly wherever an entity is categorised, and their absence is a
500 rather than a validation error. Defaulted to identity when a
category is given.
interior_entities
interior_entities(
meshes: Any,
*,
category: Optional[str] = None,
opening_factor: Optional[float] = None,
) -> Dict[str, Dict[str, Any]]
Convert a whole map of flat meshes into interior entities.
Takes the AreaBuildings returned by client.buildings.get_area(), its
.buildings mapping, or any {id: mesh} dict, and returns a map ready
to pass as context_geometry / barriers / spatial_volumes.
The intended use, and the reason this exists:
area = client.buildings.get_area(site_polygon)
request = DaylightFactorModelRequest(
analysis_type=AnalysesName.daylight_factor,
barriers=my_room_barriers,
sensor_points=my_points,
context_geometry=interior_entities(area), # neighbours as occluders
)
Without the conversion those neighbours are silently dropped and the room reads far brighter than it is.