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

.. only:: html

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

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

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

.. _sphx_glr_examples_06_advanced_ifc_to_unstructured_grid.py:


Collapse an IFC building into a single UnstructuredGrid
=======================================================

IFC files arrive as deeply-nested :class:`pyvista.MultiBlock` trees
(building / storey / element). For some downstream analyses you want
one mesh, with each cell tagged by its source element. Combine the
tree and carry an element id onto cell data so downstream code can
filter by element without walking the tree.

This uses a real BIM model: the buildingSMART "Single-family house"
sample (CC-BY 4.0, buildingSMART International), an IFC4 project with
a full site / building / storey hierarchy, walls, slabs, and property
sets.

.. GENERATED FROM PYTHON SOURCE LINES 18-26

.. code-block:: Python


    import numpy as np
    import pandas as pd
    import pyvista as pv

    import pyvista_cad
    from pyvista_cad.examples import downloads








.. GENERATED FROM PYTHON SOURCE LINES 27-28

Read the real IFC building.

.. GENERATED FROM PYTHON SOURCE LINES 28-32

.. code-block:: Python


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






.. 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 (0x7f6fa5f80100)
      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-a939c803-ea83-4b60-a110-510e76915891' class='pv-section-summary-in' type='checkbox' checked /><label for='section-a939c803-ea83-4b60-a110-510e76915891' 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 33-36

Drop stray geo-reference / survey markers placed far from the house
(a robust MAD test on block position, not a brittle name/type rule)
so they do not skew the combined grid's bounds.

.. GENERATED FROM PYTHON SOURCE LINES 36-39

.. code-block:: Python


    mb = mb.cad.drop_spatial_outliers()








.. GENERATED FROM PYTHON SOURCE LINES 40-42

Tag each leaf block's cells with a numeric id and its IFC type,
then combine into a single :class:`~pyvista.UnstructuredGrid`.

.. GENERATED FROM PYTHON SOURCE LINES 42-59

.. code-block:: Python


    rows = []
    for i, (path, block) in enumerate(mb.cad.walk()):
        if not isinstance(block, pv.DataSet) or block.n_cells == 0:
            continue
        block['element_id'] = np.full(block.n_cells, i, dtype=np.int32)
        rows.append(
            {
                'element_id': i,
                'path': str(path),
                'ifc_type': block.field_data.get('cad.ifc_type', [b''])[0],
            }
        )

    combined = mb.combine(merge_points=False)
    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>element_id</th>
          <th>path</th>
          <th>ifc_type</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th>0</th>
          <td>5</td>
          <td>environment - site/house - site/Single-family ...</td>
          <td>IfcFurniture</td>
        </tr>
        <tr>
          <th>1</th>
          <td>6</td>
          <td>environment - site/house - site/Single-family ...</td>
          <td>IfcSlab</td>
        </tr>
        <tr>
          <th>2</th>
          <td>7</td>
          <td>environment - site/house - site/Single-family ...</td>
          <td>IfcWall</td>
        </tr>
        <tr>
          <th>3</th>
          <td>8</td>
          <td>environment - site/house - site/Single-family ...</td>
          <td>IfcWall</td>
        </tr>
        <tr>
          <th>4</th>
          <td>9</td>
          <td>environment - site/house - site/Single-family ...</td>
          <td>IfcWall</td>
        </tr>
        <tr>
          <th>5</th>
          <td>10</td>
          <td>environment - site/house - site/Single-family ...</td>
          <td>IfcWall</td>
        </tr>
        <tr>
          <th>6</th>
          <td>11</td>
          <td>environment - site/house - site/Single-family ...</td>
          <td>IfcSpatialZone</td>
        </tr>
        <tr>
          <th>7</th>
          <td>12</td>
          <td>environment - site/house - site/Single-family ...</td>
          <td>IfcBuildingElementProxy</td>
        </tr>
        <tr>
          <th>8</th>
          <td>13</td>
          <td>living room</td>
          <td>IfcSpace</td>
        </tr>
        <tr>
          <th>9</th>
          <td>14</td>
          <td>entry hall</td>
          <td>IfcSpace</td>
        </tr>
        <tr>
          <th>10</th>
          <td>15</td>
          <td>house - roof - slab left</td>
          <td>IfcSlab</td>
        </tr>
        <tr>
          <th>11</th>
          <td>16</td>
          <td>house - roof - slab right</td>
          <td>IfcSlab</td>
        </tr>
      </tbody>
    </table>
    </div>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 60-61

The combined grid carries ``element_id`` on its cells.

.. GENERATED FROM PYTHON SOURCE LINES 61-64

.. code-block:: Python


    combined






.. 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'>UnstructuredGrid (0x7f6fa5f80ac0)
      N Cells:    331
      N Points:   193
      X Bounds:   2.700e+00, 8.900e+00
      Y Bounds:   2.700e+00, 9.300e+00
      Z Bounds:   -5.987e-01, 5.700e+00
      N Arrays:   9</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-ug-g1" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stop-color="#ffd040"/>
          <stop offset="100%" stop-color="#376fa0"/>
        </linearGradient>
      </defs>
      <polygon points="3,10 8,5 14,7 13,13 6,14" fill="#376fa0" opacity="0.9"/>
      <polygon points="14,7 22,4 20,12" fill="url(#pv-ug-g1)" opacity="0.85"/>
      <polygon points="22,4 29,9 27,17 20,12" fill="#1a4a70" opacity="0.85"/>
      <polygon points="13,13 20,12 16,20" fill="#ffd040" opacity="0.8"/>
      <polygon points="6,14 13,13 16,20 10,24 4,20" fill="#376fa0" opacity="0.8"/>
      <polygon points="16,20 10,24 18,28" fill="#1a4a70" opacity="0.85"/>
      <polygon points="20,12 27,17 26,25 18,28 16,20" fill="url(#pv-ug-g1)" opacity="0.8"/>
      <g stroke="rgba(255,255,255,0.6)" stroke-width="0.5" fill="none">
        <polygon points="3,10 8,5 14,7 13,13 6,14"/>
        <polygon points="14,7 22,4 20,12"/>
        <polygon points="22,4 29,9 27,17 20,12"/>
        <line x1="13" y1="13" x2="20" y2="12"/>
        <line x1="13" y1="13" x2="16" y2="20"/>
        <line x1="20" y1="12" x2="16" y2="20"/>
        <polygon points="6,14 13,13 16,20 10,24 4,20"/>
        <line x1="16" y1="20" x2="10" y2="24"/>
        <line x1="10" y1="24" x2="18" y2="28"/>
        <line x1="16" y1="20" x2="18" y2="28"/>
        <polygon points="20,12 27,17 26,25 18,28 16,20"/>
      </g>
      <g fill="rgba(255,255,255,0.8)">
        <circle cx="3" cy="10" r="0.9"/>
        <circle cx="8" cy="5" r="0.9"/>
        <circle cx="14" cy="7" r="0.9"/>
        <circle cx="22" cy="4" r="0.9"/>
        <circle cx="29" cy="9" r="0.9"/>
        <circle cx="13" cy="13" r="0.9"/>
        <circle cx="20" cy="12" r="0.9"/>
        <circle cx="6" cy="14" r="0.9"/>
        <circle cx="27" cy="17" r="0.9"/>
        <circle cx="16" cy="20" r="0.9"/>
        <circle cx="4" cy="20" r="0.9"/>
        <circle cx="10" cy="24" r="0.9"/>
        <circle cx="26" cy="25" r="0.9"/>
        <circle cx="18" cy="28" r="0.9"/>
      </g>
    </svg>
    </span><div class='pv-header-text'><div class='pv-obj-type'>UnstructuredGrid <span class='pv-header-badge'>193 points</span> <span class='pv-header-badge'>331 cells</span> <span class='pv-header-badge'>27 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='(2.700000000000038, 8.90000000000023, 2.6999999999998625, 9.299999999999992, -0.5986920309973202, 5.700000000000075)' onclick="navigator.clipboard.writeText(this.dataset.copy)">⧉</button><span class='pv-meta-entry'><span class='pv-meta-label'>X</span> [2.700e+00, 8.900e+00]</span><span class='pv-meta-entry'><span class='pv-meta-label'>Y</span> [2.700e+00, 9.300e+00]</span><span class='pv-meta-entry'><span class='pv-meta-label'>Z</span> [-5.987e-01, 5.700e+00]</span></div></div><ul class='pv-sections'><li class='pv-section-item'><input id='section-25025ea5-4a97-4053-bcfc-e37960e6d9fe' class='pv-section-summary-in' type='checkbox' checked /><label for='section-25025ea5-4a97-4053-bcfc-e37960e6d9fe' class='pv-section-summary' title='Expand/collapse section'>Cell Data: <span>(1)</span></label><div class='pv-section-inline-details'>element_id <span class='pv-badge pv-badge-active'>active</span></div><div class='pv-section-details'><ul class='pv-var-list'><li class='pv-var-item'><div class='pv-var-name pv-var-name-active'><span>element_id</span><button class='pv-copy-btn' title='Copy to clipboard' data-copy='element_id' onclick="navigator.clipboard.writeText(this.dataset.copy)">⧉</button></div><div class='pv-var-dims'>scalar</div><div class='pv-var-dtype'>int32</div><div class='pv-var-range'>[5.000e+00, 1.600e+01]</div><div class='pv-var-badges'> <span class='pv-badge pv-badge-active'>active</span></div></li></ul></div></li><li class='pv-section-item'><input id='section-1bb218f6-e5cd-4f70-902a-d7d266405438' class='pv-section-summary-in' type='checkbox' checked /><label for='section-1bb218f6-e5cd-4f70-902a-d7d266405438' class='pv-section-summary' title='Expand/collapse section'>Field Data: <span>(8)</span></label><div class='pv-section-inline-details'></div><div class='pv-section-details'><ul class='pv-var-list'><li class='pv-var-item'><div class='pv-var-name'><span>cad.color</span><button class='pv-copy-btn' title='Copy to clipboard' data-copy='cad.color' onclick="navigator.clipboard.writeText(this.dataset.copy)">⧉</button></div><div class='pv-var-dims'>(3,)</div><div class='pv-var-dtype'>float64</div><div class='pv-var-range'></div><div class='pv-var-badges'></div></li><li class='pv-var-item'><div class='pv-var-name'><span>cad.backend</span><button class='pv-copy-btn' title='Copy to clipboard' data-copy='cad.backend' onclick="navigator.clipboard.writeText(this.dataset.copy)">⧉</button></div><div class='pv-var-dims'>(1,)</div><div class='pv-var-dtype'>&lt;U12</div><div class='pv-var-range'></div><div class='pv-var-badges'></div></li><li class='pv-var-item'><div class='pv-var-name'><span>cad.source_format</span><button class='pv-copy-btn' title='Copy to clipboard' data-copy='cad.source_format' onclick="navigator.clipboard.writeText(this.dataset.copy)">⧉</button></div><div class='pv-var-dims'>(1,)</div><div class='pv-var-dtype'>&lt;U3</div><div class='pv-var-range'></div><div class='pv-var-badges'></div></li><li class='pv-var-item'><div class='pv-var-name'><span>cad.guid</span><button class='pv-copy-btn' title='Copy to clipboard' data-copy='cad.guid' onclick="navigator.clipboard.writeText(this.dataset.copy)">⧉</button></div><div class='pv-var-dims'>(1,)</div><div class='pv-var-dtype'>&lt;U22</div><div class='pv-var-range'></div><div class='pv-var-badges'></div></li><li class='pv-var-item'><div class='pv-var-name'><span>cad.ifc_type</span><button class='pv-copy-btn' title='Copy to clipboard' data-copy='cad.ifc_type' onclick="navigator.clipboard.writeText(this.dataset.copy)">⧉</button></div><div class='pv-var-dims'>(1,)</div><div class='pv-var-dtype'>&lt;U12</div><div class='pv-var-range'></div><div class='pv-var-badges'></div></li><li class='pv-var-item'><div class='pv-var-name'><span>cad.label</span><button class='pv-copy-btn' title='Copy to clipboard' data-copy='cad.label' onclick="navigator.clipboard.writeText(this.dataset.copy)">⧉</button></div><div class='pv-var-dims'>(1,)</div><div class='pv-var-dtype'>&lt;U7</div><div class='pv-var-range'></div><div class='pv-var-badges'></div></li><li class='pv-var-item'><div class='pv-var-name'><span>cad.units</span><button class='pv-copy-btn' title='Copy to clipboard' data-copy='cad.units' onclick="navigator.clipboard.writeText(this.dataset.copy)">⧉</button></div><div class='pv-var-dims'>(1,)</div><div class='pv-var-dtype'>&lt;U2</div><div class='pv-var-range'></div><div class='pv-var-badges'></div></li><li class='pv-var-item'><div class='pv-var-name'><span>cad.material</span><button class='pv-copy-btn' title='Copy to clipboard' data-copy='cad.material' onclick="navigator.clipboard.writeText(this.dataset.copy)">⧉</button></div><div class='pv-var-dims'>(1,)</div><div class='pv-var-dtype'>&lt;U14</div><div class='pv-var-range'></div><div class='pv-var-badges'></div></li></ul></div></li></ul></div></div>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 65-66

Render the building colored by element id.

.. GENERATED FROM PYTHON SOURCE LINES 66-70

.. code-block:: Python


    pl = pv.Plotter()
    pl.add_mesh(combined, scalars='element_id', cmap='tab20', show_edges=True, edge_color='black')
    pl.show()







.. tab-set::



   .. tab-item:: Static Scene



            
     .. image-sg:: /examples/06_advanced/images/sphx_glr_ifc_to_unstructured_grid_001.png
        :alt: ifc to unstructured grid
        :srcset: /examples/06_advanced/images/sphx_glr_ifc_to_unstructured_grid_001.png
        :class: sphx-glr-single-img
     


   .. tab-item:: Interactive Scene



       .. offlineviewer:: /home/runner/work/pyvista-cad/pyvista-cad/doc/examples/06_advanced/images/sphx_glr_ifc_to_unstructured_grid_001.vtksz







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

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


.. _sphx_glr_download_examples_06_advanced_ifc_to_unstructured_grid.py:

.. only:: html

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

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

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

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

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

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

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