RevitAPI: Get/Create FilledRegionType

There is no method to create new FilledRegionType. But it does not mean we can not duplicate existing one and adjust its parameters. Read More if you want to see how to Get or Create FilledRegionType.

Revit API

πŸ“Introduction

If you are reading this, then you have a question in your mind: How to get or create new FilledRegionType in Revit API. And if you browsed through available classes and methods in Revit API documentation, you might have realized that there is no way to create a new FilledRegionType.

However, it does not mean we can’t take existing one, duplicate it and then modify all necessary parameter so it’s indeed a new FilledRegionType.

So I am going to take you through all the steps to write code to Get existing FilledRegionType or create a new one if it does not exist. That might be useful for many new tools.

πŸ‘‰ Get Existing FilledRegionType by Name

First, check if the desired FilledRegionType already exists. If you are going to use a tool to create new FilledRegionType it should already exist in your Revit Project on the second run. So let’s have a look how can we get existing FilledRegionType by name.

πŸ‘‡ So let’s have a look how can we get existing FilledRegionType by name.

code
# Variables
doc      = __revit__.ActiveUIDocument.Document
uidoc    = __revit__.ActiveUIDocument
app      = __revit__.Application
rvt_year = int(app.VersionNumber)

# Function
def get_filled_region(filled_region_name):
"""Function to get FilledRegionType by Name"""

# Create Filter
param_id = ElementId(BuiltInParameter.ALL_MODEL_TYPE_NAME)
pvp = ParameterValueProvider(param_id )
condition = FilterStringEquals()
if rvt_year < 2022:
    fRule = FilterStringRule(pvp, condition, filled_region_name, True)
else:
    fRule FilterStringRule(pvp, condition, filled_region_name)

my_filter   = ElementParameterFilter(fRule)

# Get FilledRegionType
return FilteredElementCollector(doc).OfClass(FilledRegionType)\
.WherePasses(my_filter).FirstElement()

πŸ†• Create new FilledRegionType by using .Duplicate()

If FilledRegionType does not exist after trying to get it, we can start thinking about creating it ourselves. This will involve a few steps:

  • Define desired Pattern, Colour, Lineweight and Masking settings.
  • Get existing FilledRegionType and Duplicate it
  • Change parameters as you need

I am going to walk you through these steps.

1️⃣ Get Solid Pattern

Let’s begin by getting the right pattern for our new FilledRegionType. In my case I will look for Solid pattern, but you can write your own logic to get desired pattern based on Colour or pattern.

code
# FilledRegionType Settings
color = Color(128,128,255)
lineweight = 2
masking = False

# Get Solid Pattern
all_pats = FilteredElementCollector(doc).OfClass(FillPatternElement).ToElements()
all_solid = [pat for pat in all_pats if pat.GetFillPattern().IsSolidFill]
solid_pattern        = all_solid [0]

2️⃣ Get random FilledRegionType and Duplicate

The next step is to get a random FilledRegionType and duplicate it.

I am going to get all available FilledRegionTypes with FilteredElementCollector and randomly get the first one. Since we are going to change all the settings anyway it does not matter which one we take.

code
# Duplicate existing FilledRegionType
new_name = β€˜New Region’
random_filled_region = FilteredElementCollector(doc).OfClass(FilledRegionType)\
.FirstElement()
new_region= random_filled_region.Duplicate(new_name)

Now we have our new FilledRegionType with desired name and we can start changing its settings.

3️⃣ Apply new Settings to FilledRegionType

The last step is to change settings, and it’s not complicated. All of these settings are a readable an writable property of FilledRegionType, so it’s going to be very easy to set new values.

code
# Set PatternΒ Β Β  
new_region.BackgroundPatternId = ElementId(-1)Β Β  #None
new_region.ForegroundPatternId = solid_pattern.Id

# Set ColourΒ Β Β  
new_region.BackgroundPatternColor = color
new_region.ForegroundPatternColor = color

# MaskingΒ Β Β  
new_region.IsMasking = masking

# LineWeightΒ Β Β  
new_region.LineWeight = lineweight

✨ Summary

Lastly, let's summarize everything that I have explained above into a single script that will Get or Create FilledRegionType that you want.

code
# -*- coding: utf-8 -*-
__title__   = "Get/Create FilledRegion"
__author__  = "Erik Frits"

# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ β•‘ β•šβ•β•—
# β•©β•© β•©β•©  β•šβ•β•β•©β•šβ• β•© β•šβ•β• IMPORTS
# ==================================================
# Regular + Autodesk
from Autodesk.Revit.DB import *

# ╦  ╦╔═╗╦═╗╦╔═╗╔╗ ╦  ╔═╗╔═╗
# β•šβ•—β•”β•β• β•β•£β• β•¦β•β•‘β• β•β•£β• β•©β•—β•‘  β•‘β•£ β•šβ•β•—
#  β•šβ• β•© β•©β•©β•šβ•β•©β•© β•©β•šβ•β•β•©β•β•β•šβ•β•β•šβ•β• VARIABLES
# ==================================================
doc   = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
app   = __revit__.Application
rvt_year = int(app.VersionNumber)

region_name_A = 'New Region A'
region_name_B = 'New Region B'

# Get Solid Pattern
all_patterns       = FilteredElementCollector(doc).OfClass(FillPatternElement).ToElements()
all_solid_patterns = [pat for pat in all_patterns if pat.GetFillPattern().IsSolidFill]
solid_pattern      = all_solid_patterns[0]


# ╔═╗╦ ╦╔╗╔╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
# β• β•£ β•‘ β•‘β•‘β•‘β•‘β•‘   β•‘ β•‘β•‘ β•‘β•‘β•‘β•‘β•šβ•β•—
# β•š  β•šβ•β•β•β•šβ•β•šβ•β• β•© β•©β•šβ•β•β•β•šβ•β•šβ•β•
def get_filled_region(filled_region_name):
    """Function to get FireWall Types based on FamilyName"""
    # Create Filter
    pvp         = ParameterValueProvider(ElementId(BuiltInParameter.ALL_MODEL_TYPE_NAME))
    condition   = FilterStringEquals()
    fRule =     FilterStringRule(pvp, condition, filled_region_name, True) if rvt_year < 2022 \
             else FilterStringRule(pvp, condition, filled_region_name)
    my_filter   = ElementParameterFilter(fRule)

    # Get Types
    return FilteredElementCollector(doc).OfClass(FilledRegionType).WherePasses(my_filter).FirstElement()


def create_RegionType(name, color, masking = False, lineweight = 1):
    #type: (str, Color, bool, int) -> FilledRegionType
    """Create FilledRegionType with Solid Pattern."""
    random_filled_region = FilteredElementCollector(doc).OfClass(FilledRegionType).FirstElement()
    new_region           = random_filled_region.Duplicate(name)

    # Set Solid Pattern
    new_region.BackgroundPatternId = ElementId(-1)
    new_region.ForegroundPatternId = solid_pattern.Id

    # Set Colour
    new_region.BackgroundPatternColor = color
    new_region.ForegroundPatternColor = color

    # Masking
    new_region.IsMasking = masking

    # LineWeight
    new_region.LineWeight = lineweight

    return new_region


# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# β•© β•©β•© β•©β•©β•β•šβ• MAIN
# ==================================================

# Try to get existing FilledRegions
region_A = get_filled_region(region_name_A)
region_B = get_filled_region(region_name_B)

with Transaction(doc,__title__) as t:
    t.Start()
    # Create new if does not exist
    if not region_A: region_A = create_RegionType(name = region_name_A, color = Color(255,128,128))
    if not region_B: region_B = create_RegionType(name = region_name_B, color = Color(128,128,255))
    t.Commit()

# Print Names of Regions:
print(Element.Name.GetValue(region_A))
print(Element.Name.GetValue(region_B))