pyRevit

Code
Library
Find Intersecting Rooms and Areas
# -*- coding: utf-8 -*-
__title__ = "Find Intersecting Rooms&Areas"
__doc__ = """Date = 18.04.2024
__________________________
Description:
Find Intersecting Rooms&Areas and write Area.Name to Room.Name
(Adjust to your own needs)
_____________________________________________________________________
How-To:
- Run the Tool
- Select AreaScheme of desired Areas
_____________________________________________________________________
Author: Erik Frits"""
# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩ ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
#==================================================
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Architecture import Room
from pyrevit import forms
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝
#==================================================
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
# ╔═╗╦ ╦╔╗╔╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
# ╠╣ ║ ║║║║║ ║ ║║ ║║║║╚═╗
# ╚ ╚═╝╝╚╝╚═╝ ╩ ╩╚═╝╝╚╝╚═╝
#_____________________________________________________________________
# 📦 Function to create a solid from an Area
def create_area_solid(area):
area_boundary = area.GetBoundarySegments(SpatialElementBoundaryOptions())
if area_boundary:
if len(area_boundary) == 0:
return None
profile = CurveLoop()
for curve in area_boundary[0]: # First loop is the outer boundary
profile.Append(curve.GetCurve())
extrusion_height = 10.0 # ⚠️ Random Height in Feet! ~3m
return GeometryCreationUtilities.CreateExtrusionGeometry([profile], XYZ.BasisZ, extrusion_height)
#✂️ Function to check if point is inside a solid
def is_point_inside_solid(point, solid):
# Create a tiny line from Point
line = Line.CreateBound(point, XYZ(point.X, point.Y, point.Z + 0.01)) # Create Tiny Line
tolerance = 0.00001
# Create Intersection Options
opts = SolidCurveIntersectionOptions()
opts.ResultType = SolidCurveIntersectionMode.CurveSegmentsInside
# Intersect Line with Geometry
sci = solid.IntersectWithCurve(line, opts)
for i,x in enumerate(sci):
curve = sci.GetCurveSegment(i)
pt_start = curve.GetEndPoint(0)
pt_end = curve.GetEndPoint(1)
if point.IsAlmostEqualTo(pt_start, tolerance) or point.IsAlmostEqualTo(pt_end, tolerance):
return True
# ╔╦╗╔═╗╦╔╗╔
# ║║║╠═╣║║║║
# ╩ ╩╩ ╩╩╝╚╝
#_____________________________________________________________________
from collections import defaultdict
#👉 Get Rooms & Areas
rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().ToElements()
all_areas = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Areas).WhereElementIsNotElementType().ToElements()
#🔎 Sort Areas by AreaScheme
dict_areas = defaultdict(list) # List will be default value for new keys!
for area in all_areas:
dict_areas[area.AreaScheme.Name].append(area)
#_____________________________________________________________________
from pyrevit import forms
# 👉 Select AreaScheme
sel_area_scheme = forms.SelectFromList.show(dict_areas.keys(), button_name='Select AreaScheme')
if not sel_area_scheme:
forms.alert('No AreaScheme was selected. Please Try Again')
areas = dict_areas[sel_area_scheme]
#_____________________________________________________________________
#🔓 Start transaction to modify the document
t = Transaction(doc, "Update Rooms")
t.Start()
for area in areas:
try:
area_solid = create_area_solid(area)
if area_solid:
for room in rooms:
room_point = room.Location.Point
if is_point_inside_solid(room_point, area_solid):
room.Name = Element.Name.GetValue(area) #Abstract Example
#👇 Write something to a Parameter...
# value = area.Name
# room.LookupParameter("SharedParamName").Set(value)
except:
# ⚠️ Print Error Message if Fails
import traceback
print(traceback.format_exc())
t.Commit() #🔒

⌨️ Happy Coding!
Erik Frits