Skip to main content

Goal

Find walls, doors, rooms, and other elements in a received model graph — and build indexes for QA checks, schedules, and quantity reports.

What you will build

Queries that count elements by category, check required properties, find duplicate applicationId values, and group quantities by level.

When to use this

After Receive2 on connector-published data — before CSV export, version comparison, or sending analysis results back. Read BIM data patterns first if property names are unfamiliar. The recommended approach for most filtering tasks is Flatten() on the root object, then filter on DataObject.properties. Use GraphTraversal with DefaultTraversal only when you need parent context or connector-style walk rules.

Prerequisites

On DataObject instances, semantic fields live in properties: dataObject.properties.GetValueOrDefault("category"). Connector-produced BIM data often uses proxy collections — see Working with Proxies.

Complete example

Complete example

How it works

Flatten vs GraphTraversal

Flatten returns every Base in the graph — the right default for filtering and indexing:
Example
GraphTraversal adds context (parent, property name) and custom walk rules:
Example
DefaultTraversal.CreateTraversalFunc() is what Rhino, Grasshopper, Revit, AutoCAD, Tekla, and Navisworks use for receive. Prefer it unless you need to walk different properties.

Building indexes for repeated lookups

Each Flatten() is O(n). Build a dictionary once for multiple lookups:
Example
An applicationId index resolves proxies:
Example

Common mistakes

Next steps

Export model data to CSV

Door and room schedules

Working with Proxies

Resolve levels and groups

Compare two model versions

Diff between publishes
Last modified on July 18, 2026