ArcGIS Blog

3D Visualization & Analytics

ArcGIS Pro

Understand and improve the exterior shell of the building layer to support your digital twin

By David Alvarez and Jared Kohler

Introduction

City planning departments are increasingly adding digital deliveries to their workflow requirements—especially for 3D digital models (BIM). City planners, architects, engineers, and stakeholders can simulate, analyze, and visualize a city’s infrastructure by integrating these plans with real-world data before physical construction starts. This allows better decision-making, improves collaboration among multidisciplinary teams, and enhances the overall efficiency and sustainability of urban development. This shift toward data-driven, integrated urban planning is reshaping how cities grow, ensuring they are more sustainable, livable, and future-proof. As urban populations continue to rise, the use of BIM in city planning will be pivotal in creating cities that can effectively address new challenges.

Before you begin

What you need

  • ArcGIS notebook included with this post
  • ArcGIS Pro 3.2 or later

Now that multiple digital models have been combined as a single feature dataset, you can now explore the result of the exterior shell to see if it meets the requirements. The image below shows the exterior shell layer is missing the roof and lower floor for both buildings and has many unnecessary interior elements like seats and pipes that will negatively impact performance.

 

Exterior shell representation
Exterior shell representation

Before you can fix the ExteriorShell feature class, you must understand how the exterior shell is created.

The exterior shell creation depends on the data type (building, bridge, road, and so on) and the data format. In this example, you will review the exterior shell from a building with source data from Revit. For a standard building shell, the ExteriorShell feature class is created by looking at the windows, doors, walls, and floors (where the attribute Function is set to Exterior). After those elements have been grouped, the next features to check are in the generic model: columns (only the architectural), stairs, and stair railings. Once all the categories have been identified, the ExteriorShell feature class is created.

The exterior shell shown above was created from a digital model that is the result of combining 46 different Revit files. Each constituent digital model has its own exterior shell feature class, and these have all been appended to a single feature class by running the BIM File To Geodatabase geoprocessing tool. Due to the varied nature of the Revit files used, not all followed the Building Shell behavior and instead brought in attributes from the Fallback Shell behavior instead.

To better understand the creation of the exterior shell for different types of structures and formats, see the graphics below.

Revit exterior shell rules for the building layer
Revit exterior shell rules for the building layer
IFC exterior shell rules for building layer
IFC exterior shell rules for building layer

The rules documented above were based on ArcGIS Pro 3.3.

Now that you understand how the exterior shell is created, you could ask the modeler or designer to fix some of the issues you discovered. In this case, the project final deliverable was already submitted, so you will instead need to fix the exterior shell directly from the geodatabase.

Complete the following workflows to improve the exterior shell of the building layer, including both the manual workflow and automation with ArcPy.

Edit the ExteriorShell feature class manually

First, you will improve the ExteriorShell feature class so the depiction of the building is more realistic.

  1. Optionally, make a copy of the ExteriorShell feature class.

This is recommended so you have better control over the elements that are going to be deleted and added to the feature class and in case you need to revert to the original ExteriorShell feature class.

  1. Open a local scene.
  2. Add the ExteriorShell feature class to the scene.

Delete elements

Next, you will delete elements.

  1. Select the element.
  2. Delete the sound baffles.
Sound baffles elements
Sound baffles elements

3. Delete the furniture.

Furniture elements
Furniture elements

4. Delete the heating pipes.

Heating Pipes elements
Heating Pipes elements

5. Delete the HVAC system.

HVAC elements
HVAC elements

Add elements

The current ExteriorShell feature class does not illustrate the roof, the first floor, or the ground floor elements.

  1. Add the Floors feature class.
  2. Navigate around the scene to get a better perspective.

 

Floors feature class
Floors feature class

3. Create a definition query based on the building level attribute by selecting BldgLevel and includes the value(s), and check the 2, 10, and 8 boxes.

Definition Query
Definition query for the floor layer

4. Ensure that the elements fit your needs for the exterior shell depiction.

Floor elements selected
Floor elements selected

You can now append these elements to the exterior shell feature class.

5. Open the Append geoprocessing tool and set the following parameters:

a. For Input Dataset, select Floors.

b. For Target Dataset, select ExteriorShell.

c. For Field Matching Type, select Use the field map to reconcile field differences.

Append Geoprocessing Tool append floor elements to Exteriorshell feature class

6. Click Run.

The ExteriorShell feature class now includes the floors that were added by the Append geoprocessing tool.

New Exteriorshell feature class
New Exteriorshell layer

Automate editing the ExteriorShell feature class

The following code shows the workflow to improve the ExteriorShell feature class so the depiction of the building is more realistic.

 


import arcpy

# Set the input geodatabase and workspace
input_gdb = r'C:\Projects\Jihlava_MultipurposeAreana_2025.gdb\Multi_Areana'
arcpy.env.workspace = input_gdb

# Define feature class and layer names
exteriorshell_fc = 'ExteriorShell_Multi_Areana'
floors_fc = 'Floors_Multi_Areana'
working_layer = "memory\\ExteriorShell_lyr"
working_floors_layer = "memory\\Floor_lyr"
temp_fc = "ExteriorShell_Temp"

# Delete existing temporary layer if it exists
if arcpy.Exists(working_layer):
    arcpy.Delete_management(working_layer)
# Create a feature layer for processing
arcpy.management.MakeFeatureLayer(exteriorshell_fc, working_layer)

filter_field = 'DocName'
filter_values = [
    '19_024_JIHL_I_ESI',
    '19_024_JIHL_I_INT',
    '19_024_JIHL_I_PODHLED_AKU',
    '19_024_JIHL_I_TRB',
    '19_024_JIHL_I_VZT',
    '19_024_JIHL_III_ESI',
    '19_024_JIHL_III_INT',
    '19_024_JIHL_III_UTCH',
    '19_024_JIHL_III_VZT'
]
# Build SQL WHERE clause to exclude these DocNames
where_clause = f"{filter_field} NOT IN ({', '.join([repr(name) for name in filter_values])})"
print(where_clause)

# Select features not in the excluded DocNames
arcpy.management.SelectLayerByAttribute(working_layer, "NEW_SELECTION", where_clause)

# Delete existing temp feature class if it exists
if arcpy.Exists(temp_fc):
    arcpy.Delete_management(temp_fc)

# Copy the selected features to a new feature class
arcpy.management.CopyFeatures(working_layer, temp_fc)

# Delete existing temporary floor layer if it exists
if arcpy.Exists(working_floors_layer):
    arcpy.Delete_management(working_floors_layer)
# Create a feature layer from the floors feature class
arcpy.management.MakeFeatureLayer(floors_fc, working_floors_layer)

filter_field = 'BldgLevel'
filter_values = [2, 8, 10]
# Build SQL WHERE clause to select these BldgLevels
floors_where_clause = f"{filter_field} IN ({', '.join([repr(name) for name in filter_values])})"
print(floors_where_clause)

# Select floor features based on the where clause and append to temp_fc
arcpy.management.SelectLayerByAttribute(working_floors_layer, "NEW_SELECTION", floors_where_clause)
arcpy.management.Append(inputs=working_floors_layer, target=temp_fc, schema_type="NO_TEST")

# Replace the original exterior shell feature class with the updated one
if arcpy.Exists(exteriorshell_fc):
    arcpy.Delete_management(exteriorshell_fc)
    arcpy.AddMessage('Exterior Shell Layer Deleted')
    arcpy.Rename_management(temp_fc, exteriorshell_fc)
    arcpy.AddMessage('Generalized Layer Renamed to Exterior Shell')
    arcpy.AlterAliasName(exteriorshell_fc, 'ExteriorShell')

# Optional cleanup of temporary layers
for lyr in [working_layer, working_floors_layer]:
    if arcpy.Exists(lyr):
        arcpy.Delete_management(lyr)

This automation code is specific to this project, but you can use it as an example to implement automation with your data.

Summary

After following these steps, you can now automate, improved and added more detail to an exterior shell, and it is ready to be used in ArcGIS Pro or on ArcGIS Online.

Acknowledgement

Thank you to ARCDATA PRAHA, s.r.o. and the City of Jihlava (Magistrát města Jihlavy) for sharing the digital models.

 

Download the ArcGIS Notebook

 

Share this article

Subscribe
Notify of
0 Comments
Oldest
Newest
Inline Feedbacks
View all comments