
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples/04_metadata/assembly_tree_walk.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_examples_04_metadata_assembly_tree_walk.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_04_metadata_assembly_tree_walk.py:


Walk and filter a real IFC assembly
===================================

The ``.cad`` accessor adds ``walk``, ``find``, and ``flatten`` for
hierarchical CAD assemblies. ``walk`` yields ``(path, block)`` pairs;
``find`` filters by metadata predicates; ``flatten`` collapses every
leaf to a single-level MultiBlock with path-named blocks.

This example walks a real BIM model, the buildingSMART
"Single-family house" sample (CC-BY 4.0, buildingSMART International),
and finds all walls by their IFC type, the canonical first step in
any BIM analysis.

.. GENERATED FROM PYTHON SOURCE LINES 17-24

.. code-block:: Python


    import pandas as pd
    import pyvista as pv

    import pyvista_cad
    from pyvista_cad.examples import downloads








.. GENERATED FROM PYTHON SOURCE LINES 25-26

Read the real IFC building.

.. GENERATED FROM PYTHON SOURCE LINES 26-30

.. code-block:: Python


    root = pyvista_cad.read_ifc(downloads.ifc_building_path())
    root






.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">
    <div><style>/* PyVista HTML repr stylesheet.
     * Uses pv- prefix to avoid conflicts with other libraries.
     */

    :root {
      --pv-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));
      --pv-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));
      --pv-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));
      --pv-border-color: var(--jp-border-color2, #e0e0e0);
      --pv-disabled-color: var(--jp-layout-color3, #bdbdbd);
      --pv-background-color-row-even: var(--jp-layout-color1, #f5f5f5);
      --pv-background-color-row-odd: var(--jp-layout-color2, #eeeeee);
      --pv-badge-active: #1b5e20;
      --pv-badge-normals: #0d47a1;
      --pv-badge-vectors: #00695c;
      --pv-badge-tcoords: #4527a0;
    }

    body[data-jp-theme-light="false"] {
      --pv-font-color0: var(--jp-content-font-color0, rgba(255, 255, 255, 1));
      --pv-font-color2: var(--jp-content-font-color2, rgba(255, 255, 255, 0.54));
      --pv-font-color3: var(--jp-content-font-color3, rgba(255, 255, 255, 0.38));
      --pv-border-color: var(--jp-border-color2, #424242);
      --pv-disabled-color: var(--jp-layout-color3, #616161);
      --pv-background-color-row-even: var(--jp-layout-color1, #1a1a1a);
      --pv-background-color-row-odd: var(--jp-layout-color2, #252525);
      --pv-badge-active: #66bb6a;
      --pv-badge-normals: #64b5f6;
      --pv-badge-vectors: #4db6ac;
      --pv-badge-tcoords: #b39ddb;
    }

    html[theme="dark"],
    html[data-theme="dark"],
    body[data-theme="dark"],
    body.vscode-dark {
      --pv-font-color0: rgba(255, 255, 255, 1);
      --pv-font-color2: rgba(255, 255, 255, 0.54);
      --pv-font-color3: rgba(255, 255, 255, 0.38);
      --pv-border-color: #424242;
      --pv-disabled-color: #616161;
      --pv-background-color-row-even: #1a1a1a;
      --pv-background-color-row-odd: #252525;
      --pv-badge-active: #66bb6a;
      --pv-badge-normals: #64b5f6;
      --pv-badge-vectors: #4db6ac;
      --pv-badge-tcoords: #b39ddb;
    }

    /* OS-level dark mode fallback: applies when no explicit data-theme is set */
    @media (prefers-color-scheme: dark) {
      html:not([data-theme="light"]) {
        --pv-font-color0: rgba(255, 255, 255, 1);
        --pv-font-color2: rgba(255, 255, 255, 0.54);
        --pv-font-color3: rgba(255, 255, 255, 0.38);
        --pv-border-color: #424242;
        --pv-disabled-color: #616161;
        --pv-background-color-row-even: #1a1a1a;
        --pv-background-color-row-odd: #252525;
        --pv-badge-active: #66bb6a;
        --pv-badge-normals: #64b5f6;
        --pv-badge-vectors: #4db6ac;
        --pv-badge-tcoords: #b39ddb;
      }
    }

    .pv-wrap {
      display: block !important;
      min-width: 300px;
      max-width: 700px;
      line-height: 1.6;
      padding-bottom: 4px;
      font-family: var(--jp-ui-font-family, sans-serif);
      font-size: var(--jp-ui-font-size1, 13px);
      color: var(--pv-font-color0);
    }

    .pv-text-repr-fallback {
      display: none;
    }

    /* Header */
    .pv-header {
      display: flex;
      align-items: center;
      gap: 8px;
      padding-top: 6px;
      padding-bottom: 6px;
      border-bottom: solid 1px var(--pv-border-color);
      margin-bottom: 4px;
    }

    .pv-header-text {
      display: flex;
      flex-direction: column;
      gap: 1px;
      min-width: 0;
      flex: 1;
    }

    .pv-obj-type {
      font-weight: 600;
      color: var(--pv-font-color0);
    }

    .pv-header-badge {
      display: inline-block;
      font-size: 0.75em;
      font-weight: 600;
      padding: 2px 7px;
      border-radius: 3px;
      color: var(--pv-font-color2);
      border: 1px solid var(--pv-border-color);
      white-space: nowrap;
    }

    /* Metadata (always-visible key-value rows) */
    .pv-metadata {
      margin: 4px 0 6px 0;
      font-size: 0.92em;
      line-height: 1.5;
    }

    .pv-meta-row {
      display: flex;
      flex-wrap: wrap;
      gap: 1px 14px;
      padding: 1px 0;
    }

    .pv-meta-row-label {
      color: var(--pv-font-color2);
      font-weight: 500;
      white-space: nowrap;
      min-width: 60px;
    }

    .pv-meta-entry {
      white-space: nowrap;
    }

    /* Copy-to-clipboard button */
    .pv-copy-btn {
      display: inline-block;
      cursor: pointer;
      opacity: 0.5;
      font-size: 0.85em;
      padding: 0 3px;
      vertical-align: middle;
      transition: opacity 0.15s;
      user-select: none;
      border: none;
      background: none;
      color: var(--pv-font-color3);
    }

    .pv-copy-btn:hover {
      opacity: 1;
      color: var(--pv-font-color0);
    }

    .pv-meta-label {
      color: var(--pv-font-color3);
      font-weight: 400;
      padding-right: 2px;
    }

    /* Sections grid */
    .pv-sections {
      padding-left: 0 !important;
      display: grid;
      grid-template-columns: 150px auto auto auto 1fr 20px 20px;
      margin-block-start: 0;
      margin-block-end: 0;
      list-style: none;
    }

    .pv-section-item {
      display: contents;
    }

    /* Hidden checkbox for expand/collapse */
    .pv-section-item > input {
      display: block;
      opacity: 0;
      height: 0;
      margin: 0;
    }

    .pv-section-item > input + label {
      color: var(--pv-disabled-color);
    }

    .pv-section-item > input:enabled + label {
      cursor: pointer;
      color: var(--pv-font-color2);
    }

    .pv-section-item > input:enabled + label:hover {
      color: var(--pv-font-color0);
    }

    /* Section summary (left column label) */
    .pv-section-summary {
      grid-column: 1;
      color: var(--pv-font-color2);
      font-weight: 500;
      white-space: nowrap;
    }

    .pv-section-summary > span {
      display: inline-block;
      padding-left: 0.3em;
    }

    .pv-section-summary-in:disabled + label {
      color: var(--pv-font-color2);
    }

    /* Expand/collapse arrows */
    .pv-section-summary-in + label:before {
      display: inline-block;
      content: "\25b6";
      font-size: 11px;
      width: 15px;
      text-align: center;
    }

    .pv-section-summary-in:disabled + label:before {
      color: var(--pv-disabled-color);
    }

    .pv-section-summary-in:checked + label:before {
      content: "\25bc";
    }

    .pv-section-summary-in:checked + label > span {
      display: none;
    }

    .pv-section-summary,
    .pv-section-inline-details {
      padding-top: 4px;
    }

    .pv-section-inline-details {
      grid-column: 2 / -1;
    }

    .pv-section-details {
      grid-column: 1 / -1;
      margin-top: 4px;
      margin-bottom: 5px;
    }

    .pv-section-summary-in ~ .pv-section-details {
      display: none;
    }

    .pv-section-summary-in:checked ~ .pv-section-inline-details {
      display: none;
    }

    .pv-section-summary-in:checked ~ .pv-section-details {
      display: block;
    }

    .pv-section-summary-in:checked ~ .pv-section-details:has(.pv-var-list) {
      display: contents;
    }

    /* Variable (array) list */
    .pv-var-list,
    .pv-var-item {
      display: contents;
    }

    .pv-var-item > div,
    .pv-var-item label,
    .pv-var-item > .pv-var-name span {
      background-color: var(--pv-background-color-row-even);
      border-color: var(--pv-background-color-row-odd);
      margin-bottom: 0;
      padding-top: 2px;
    }

    .pv-var-list > li:nth-child(odd) > div,
    .pv-var-list > li:nth-child(odd) > label,
    .pv-var-list > li:nth-child(odd) > .pv-var-name span {
      background-color: var(--pv-background-color-row-odd);
      border-color: var(--pv-background-color-row-even);
    }

    .pv-var-name {
      grid-column: 1;
    }

    .pv-var-dims {
      grid-column: 2;
    }

    .pv-var-dtype {
      grid-column: 3;
      text-align: right;
      color: var(--pv-font-color2);
    }

    .pv-var-range {
      grid-column: 4;
      color: var(--pv-font-color3);
      font-size: 0.92em;
    }

    .pv-var-badges {
      grid-column: 5;
      padding-left: 8px;
    }

    .pv-var-name,
    .pv-var-dims,
    .pv-var-dtype,
    .pv-var-range {
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      padding-right: 10px;
    }

    .pv-var-name:hover,
    .pv-var-dims:hover,
    .pv-var-dtype:hover,
    .pv-var-range:hover {
      overflow: visible;
      width: auto;
      z-index: 1;
    }

    .pv-var-name span {
      padding-left: 25px !important;
    }

    .pv-var-name-active span {
      font-weight: 600;
    }

    /* Badges */
    .pv-badge {
      display: inline-block;
      font-size: 0.75em;
      font-weight: 600;
      padding: 1px 5px;
      border-radius: 3px;
      vertical-align: middle;
      line-height: 1.4;
    }

    .pv-badge-active {
      color: var(--pv-badge-active);
      border: 1px solid var(--pv-badge-active);
    }

    .pv-badge-normals {
      color: var(--pv-badge-normals);
      border: 1px solid var(--pv-badge-normals);
    }

    .pv-badge-vectors {
      color: var(--pv-badge-vectors);
      border: 1px solid var(--pv-badge-vectors);
    }

    .pv-badge-tcoords {
      color: var(--pv-badge-tcoords);
      border: 1px solid var(--pv-badge-tcoords);
    }

    /* Logo and Icons */
    .pv-logo {
      display: flex;
      align-items: center;
      flex-shrink: 0;
    }

    .pv-logo svg {
      width: 28px;
      height: 28px;
    }

    .pv-brand-logo {
      display: flex;
      align-items: center;
      flex-shrink: 0;
    }

    .pv-brand-logo svg {
      height: 20px;
      width: auto;
    }

    /* Children list (MultiBlock / PartitionedDataSet) */
    .pv-children-list {
      padding-left: 25px !important;
      list-style: none;
    }

    .pv-children-list li {
      padding: 1px 0;
    }

    .pv-child-name {
      font-weight: 500;
    }

    .pv-child-type {
      color: var(--pv-font-color2);
      font-style: italic;
    }

    .pv-child-type:before {
      content: "\00b7";
      padding: 0 6px;
      font-style: normal;
    }

    .pv-child-detail {
      color: var(--pv-font-color3);
      font-size: 0.9em;
    }

    .pv-child-detail:not(:empty):before {
      content: "\00b7";
      padding: 0 6px;
    }
    </style><pre class='pv-text-repr-fallback'>MultiBlock (0x7f6faa6d8fa0)
      N Blocks:   5
      X Bounds:   -2.964e+01, 8.900e+00
      Y Bounds:   -1.499e+01, 9.300e+00
      Z Bounds:   -1.300e+00, 5.700e+00</pre><div class='pv-wrap' style='display:none'><div class='pv-header'><span class='pv-logo'><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
      <defs>
        <linearGradient id="pv-mb-top1" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stop-color="#ffd040"/>
          <stop offset="100%" stop-color="#376fa0"/>
        </linearGradient>
        <linearGradient id="pv-mb-top2" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stop-color="#376fa0"/>
          <stop offset="100%" stop-color="#ffd040"/>
        </linearGradient>
      </defs>
      <polygon points="13,2 22,6 13,10 4,6" fill="url(#pv-mb-top1)" opacity="0.9"/>
      <polygon points="4,6 13,10 13,17 4,13" fill="#1a4a70" opacity="0.9"/>
      <polygon points="22,6 13,10 13,17 22,13" fill="#376fa0" opacity="0.85"/>
      <g stroke="rgba(255,255,255,0.4)" stroke-width="0.35" fill="none">
        <polygon points="13,2 22,6 13,10 4,6"/>
        <line x1="13" y1="10" x2="13" y2="17"/>
        <line x1="4" y1="6" x2="4" y2="13"/>
        <line x1="22" y1="6" x2="22" y2="13"/>
        <line x1="4" y1="13" x2="13" y2="17"/>
        <line x1="22" y1="13" x2="13" y2="17"/>
      </g>
      <polygon points="17,7 26,11 17,15 8,11" fill="url(#pv-mb-top2)" opacity="0.9"/>
      <polygon points="8,11 17,15 17,22 8,18" fill="#1a4a70" opacity="0.85"/>
      <polygon points="26,11 17,15 17,22 26,18" fill="#376fa0" opacity="0.85"/>
      <g stroke="rgba(255,255,255,0.4)" stroke-width="0.35" fill="none">
        <polygon points="17,7 26,11 17,15 8,11"/>
        <line x1="17" y1="15" x2="17" y2="22"/>
        <line x1="8" y1="11" x2="8" y2="18"/>
        <line x1="26" y1="11" x2="26" y2="18"/>
        <line x1="8" y1="18" x2="17" y2="22"/>
        <line x1="26" y1="18" x2="17" y2="22"/>
      </g>
      <polygon points="19,13 28,17 19,21 10,17" fill="url(#pv-mb-top1)" opacity="0.95"/>
      <polygon points="10,17 19,21 19,28 10,24" fill="#1a4a70" opacity="0.9"/>
      <polygon points="28,17 19,21 19,28 28,24" fill="#376fa0" opacity="0.9"/>
      <g stroke="rgba(255,255,255,0.45)" stroke-width="0.35" fill="none">
        <polygon points="19,13 28,17 19,21 10,17"/>
        <line x1="19" y1="21" x2="19" y2="28"/>
        <line x1="10" y1="17" x2="10" y2="24"/>
        <line x1="28" y1="17" x2="28" y2="24"/>
        <line x1="10" y1="24" x2="19" y2="28"/>
        <line x1="28" y1="24" x2="19" y2="28"/>
      </g>
    </svg>
    </span><div class='pv-header-text'><div class='pv-obj-type'>MultiBlock <span class='pv-header-badge'>5 blocks</span> <span class='pv-header-badge'>209 KiB</span></div></div><span class='pv-brand-logo'><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90 24">
      <text x="0" y="18" font-family="system-ui,-apple-system,sans-serif" font-size="18" font-weight="700" font-style="italic" letter-spacing="-0.5">
        <tspan fill="#3776AB" opacity="0.7">P</tspan><tspan fill="#FFD43B" opacity="0.7">y</tspan><tspan fill="#008c9e">Vista</tspan>
      </text>
    </svg>
    </span></div><div class='pv-metadata'><div class='pv-meta-row pv-copyable'><span class='pv-meta-row-label'>Bounds</span><button class='pv-copy-btn' title='Copy to clipboard' data-copy='(-29.64253434705634, 8.90000000000023, -14.98571577845881, 9.299999999999992, -1.3000000007450598, 5.700000000000075)' onclick="navigator.clipboard.writeText(this.dataset.copy)">⧉</button><span class='pv-meta-entry'><span class='pv-meta-label'>X</span> [-2.964e+01, 8.900e+00]</span><span class='pv-meta-entry'><span class='pv-meta-label'>Y</span> [-1.499e+01, 9.300e+00]</span><span class='pv-meta-entry'><span class='pv-meta-label'>Z</span> [-1.300e+00, 5.700e+00]</span></div></div><ul class='pv-sections'><li class='pv-section-item'><input id='section-5090349a-242f-41a8-977f-349a2a2af067' class='pv-section-summary-in' type='checkbox' checked /><label for='section-5090349a-242f-41a8-977f-349a2a2af067' class='pv-section-summary' title='Expand/collapse section'>Blocks: <span>(5)</span></label><div class='pv-section-inline-details'></div><div class='pv-section-details'><ul class='pv-children-list'><li><span class='pv-child-name'>environment - site</span><span class='pv-child-type'>MultiBlock</span><span class='pv-child-detail'>2 blocks · 163 KiB</span></li><li><span class='pv-child-name'>living room</span><span class='pv-child-type'>PolyData</span><span class='pv-child-detail'>16 pts · 28 cells · 11 KiB</span></li><li><span class='pv-child-name'>entry hall</span><span class='pv-child-type'>PolyData</span><span class='pv-child-detail'>8 pts · 12 cells · 11 KiB</span></li><li><span class='pv-child-name'>house - roof - slab left</span><span class='pv-child-type'>PolyData</span><span class='pv-child-detail'>8 pts · 12 cells · 12 KiB</span></li><li><span class='pv-child-name'>house - roof - slab right</span><span class='pv-child-type'>PolyData</span><span class='pv-child-detail'>20 pts · 40 cells · 12 KiB</span></li></ul></div></li></ul></div></div>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 31-35

Drop stray geo-reference / survey markers placed far from the house.
``drop_spatial_outliers`` uses a robust MAD test on block position
(markers have no reliable IFC class) and preserves the hierarchy, so
the walk below still shows the real building tree.

.. GENERATED FROM PYTHON SOURCE LINES 35-38

.. code-block:: Python


    root = root.cad.drop_spatial_outliers()








.. GENERATED FROM PYTHON SOURCE LINES 39-40

Walk the tree. Path, IFC type, and cell count.

.. GENERATED FROM PYTHON SOURCE LINES 40-58

.. code-block:: Python


    rows = []
    for path, block in root.cad.walk():
        n_cells = (
            block.n_cells
            if isinstance(block, pv.DataSet)
            else sum(b.n_cells for b in block if isinstance(b, pv.DataSet))
        )
        rows.append(
            {
                'path': str(path),
                'kind': type(block).__name__,
                'ifc_type': block.field_data.get('cad.ifc_type', [b''])[0],
                'cells': n_cells,
            }
        )
    pd.DataFrame(rows)






.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">
    <div>
    <style scoped>
        .dataframe tbody tr th:only-of-type {
            vertical-align: middle;
        }

        .dataframe tbody tr th {
            vertical-align: top;
        }

        .dataframe thead th {
            text-align: right;
        }
    </style>
    <table border="1" class="dataframe">
      <thead>
        <tr style="text-align: right;">
          <th></th>
          <th>path</th>
          <th>kind</th>
          <th>ifc_type</th>
          <th>cells</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th>0</th>
          <td>environment - site</td>
          <td>MultiBlock</td>
          <td>IfcSite</td>
          <td>0</td>
        </tr>
        <tr>
          <th>1</th>
          <td>environment - site/house - site</td>
          <td>MultiBlock</td>
          <td>IfcSite</td>
          <td>0</td>
        </tr>
        <tr>
          <th>2</th>
          <td>environment - site/house - site/Single-family ...</td>
          <td>MultiBlock</td>
          <td>IfcBuilding</td>
          <td>70</td>
        </tr>
        <tr>
          <th>3</th>
          <td>environment - site/house - site/Single-family ...</td>
          <td>MultiBlock</td>
          <td>IfcBuildingStorey</td>
          <td>133</td>
        </tr>
        <tr>
          <th>4</th>
          <td>environment - site/house - site/Single-family ...</td>
          <td>MultiBlock</td>
          <td>IfcSpace</td>
          <td>36</td>
        </tr>
        <tr>
          <th>5</th>
          <td>environment - site/house - site/Single-family ...</td>
          <td>PolyData</td>
          <td>IfcFurniture</td>
          <td>36</td>
        </tr>
        <tr>
          <th>6</th>
          <td>environment - site/house - site/Single-family ...</td>
          <td>PolyData</td>
          <td>IfcSlab</td>
          <td>73</td>
        </tr>
        <tr>
          <th>7</th>
          <td>environment - site/house - site/Single-family ...</td>
          <td>PolyData</td>
          <td>IfcWall</td>
          <td>12</td>
        </tr>
        <tr>
          <th>8</th>
          <td>environment - site/house - site/Single-family ...</td>
          <td>PolyData</td>
          <td>IfcWall</td>
          <td>12</td>
        </tr>
        <tr>
          <th>9</th>
          <td>environment - site/house - site/Single-family ...</td>
          <td>PolyData</td>
          <td>IfcWall</td>
          <td>12</td>
        </tr>
        <tr>
          <th>10</th>
          <td>environment - site/house - site/Single-family ...</td>
          <td>PolyData</td>
          <td>IfcWall</td>
          <td>24</td>
        </tr>
        <tr>
          <th>11</th>
          <td>environment - site/house - site/Single-family ...</td>
          <td>PolyData</td>
          <td>IfcSpatialZone</td>
          <td>24</td>
        </tr>
        <tr>
          <th>12</th>
          <td>environment - site/house - site/Single-family ...</td>
          <td>PolyData</td>
          <td>IfcBuildingElementProxy</td>
          <td>46</td>
        </tr>
        <tr>
          <th>13</th>
          <td>living room</td>
          <td>PolyData</td>
          <td>IfcSpace</td>
          <td>28</td>
        </tr>
        <tr>
          <th>14</th>
          <td>entry hall</td>
          <td>PolyData</td>
          <td>IfcSpace</td>
          <td>12</td>
        </tr>
        <tr>
          <th>15</th>
          <td>house - roof - slab left</td>
          <td>PolyData</td>
          <td>IfcSlab</td>
          <td>12</td>
        </tr>
        <tr>
          <th>16</th>
          <td>house - roof - slab right</td>
          <td>PolyData</td>
          <td>IfcSlab</td>
          <td>40</td>
        </tr>
      </tbody>
    </table>
    </div>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 59-60

Find every wall.

.. GENERATED FROM PYTHON SOURCE LINES 60-64

.. code-block:: Python


    walls = root.cad.find(ifc_type='IfcWall')
    pd.DataFrame({'path': [str(p) for p, _ in walls]})






.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">
    <div>
    <style scoped>
        .dataframe tbody tr th:only-of-type {
            vertical-align: middle;
        }

        .dataframe tbody tr th {
            vertical-align: top;
        }

        .dataframe thead th {
            text-align: right;
        }
    </style>
    <table border="1" class="dataframe">
      <thead>
        <tr style="text-align: right;">
          <th></th>
          <th>path</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th>0</th>
          <td>environment - site/house - site/Single-family ...</td>
        </tr>
        <tr>
          <th>1</th>
          <td>environment - site/house - site/Single-family ...</td>
        </tr>
        <tr>
          <th>2</th>
          <td>environment - site/house - site/Single-family ...</td>
        </tr>
        <tr>
          <th>3</th>
          <td>environment - site/house - site/Single-family ...</td>
        </tr>
      </tbody>
    </table>
    </div>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 65-66

Flatten the tree: every leaf becomes a path-named block.

.. GENERATED FROM PYTHON SOURCE LINES 66-69

.. code-block:: Python


    list(root.cad.flatten().keys())





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    ['environment - site/house - site/Single-family house/00 groundfloor/living room/kitchen', 'environment - site/house - site/Single-family house/00 groundfloor/floor', 'environment - site/house - site/Single-family house/00 groundfloor/house - outer wall - house right front', 'environment - site/house - site/Single-family house/00 groundfloor/house - outer wall - house right back', 'environment - site/house - site/Single-family house/00 groundfloor/house - outer wall - house left', 'environment - site/house - site/Single-family house/00 groundfloor/plumbing wall', 'environment - site/house - site/Single-family house/house - gross volume', 'environment - site/house - site/Single-family house/sand bedding', 'living room', 'entry hall', 'house - roof - slab left', 'house - roof - slab right']



.. GENERATED FROM PYTHON SOURCE LINES 70-71

Render the building with each element in its own color.

.. GENERATED FROM PYTHON SOURCE LINES 71-75

.. code-block:: Python


    pl = pv.Plotter()
    pl.add_mesh(root, multi_colors=True, show_edges=True, edge_color='black')
    pl.show()







.. tab-set::



   .. tab-item:: Static Scene



            
     .. image-sg:: /examples/04_metadata/images/sphx_glr_assembly_tree_walk_001.png
        :alt: assembly tree walk
        :srcset: /examples/04_metadata/images/sphx_glr_assembly_tree_walk_001.png
        :class: sphx-glr-single-img
     


   .. tab-item:: Interactive Scene



       .. offlineviewer:: /home/runner/work/pyvista-cad/pyvista-cad/doc/examples/04_metadata/images/sphx_glr_assembly_tree_walk_001.vtksz







.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 0.605 seconds)


.. _sphx_glr_download_examples_04_metadata_assembly_tree_walk.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: assembly_tree_walk.ipynb <assembly_tree_walk.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: assembly_tree_walk.py <assembly_tree_walk.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: assembly_tree_walk.zip <assembly_tree_walk.zip>`
