Get rooms within element

Guys,

I want to create a simple script that gives me a list of rooms that are within a component.

How to get the elements inside a boundingbox? this topic shows how to get ALL elements within a component. But that’s too much.
Yes I can filterbyboolmask but that feels like too much calculationtime.

import clr
clr.AddReference('RevitAPI')
clr.AddReference('System')
clr.AddReference('RevitNodes')
clr.AddReference('RevitServices')
import Revit
import RevitServices
from Autodesk.Revit.DB import *
from System.Collections.Generic import List
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
doc = DocumentManager.Instance.CurrentDBDocument

#Functions for list handling
def ProcessList(_func, _list):
   return map( lambda x: ProcessList(_func, x) if type(x)==list else _func(x), _list )

#Preparing input from dynamo to revit

def ToRevit(item):
	return item.ToRevitType(True)

if isinstance(IN[0], list):
	bblist = ProcessList(ToRevit, IN[0])
else:
	bblist = [ToRevit(IN[0])]

def collectElementsInBB(bb):
	outline = Outline(bb.Min, bb.Max)
	filter = BoundingBoxIntersectsFilter(outline)
	collector = FilteredElementCollector(doc, doc.ActiveView.Id).WherePasses(filter)
	return [e.ToDSType(True) for e in collector]

OUT = ProcessList(collectElementsInBB, bblist)

This script uses activeView which isn’t usefull for rooms. 3D view as active view won’t give me the rooms.
But in short, I don’t care about the activeview etc. Just want input[0] a list of components and out rooms within that component (even if rooms are nested in groups (which are within the boundingbox)).

Use BimorphNodes BoundingBox.GetElementsInside or if you need more accuracy, extract the room volume using OOTB Element.Solids, then use BimorphNodes Element.IntersectsSolid. Both nodes are optimised for rapid results.

1 Like

@Thomas_Mahon,

Thnx for your reply, will have a look at it.

Meanwhile, I think this should be right too?.. or perhaps ‘dirty coding’?

import clr
clr.AddReference('RevitAPI')
clr.AddReference('System')
clr.AddReference('RevitNodes')
clr.AddReference('RevitServices')
import Revit
import RevitServices
from Autodesk.Revit.DB import *
from System.Collections.Generic import List
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
doc = DocumentManager.Instance.CurrentDBDocument

#Functions for list handling
def ProcessList(_func, _list):
   return map( lambda x: ProcessList(_func, x) if type(x)==list else _func(x), _list )

#Preparing input from dynamo to revit

def ToRevit(item):
	return item.ToRevitType(True)

if isinstance(IN[0], list):
	bblist = ProcessList(ToRevit, IN[0])
else:
	bblist = [ToRevit(IN[0])]

def collectElementsInBB(bb):
	outline = Outline(bb.Min, bb.Max)
	filter = BoundingBoxIntersectsFilter(outline)
	collector = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WherePasses(filter)
	return [e.ToDSType(True) for e in collector]

OUT = ProcessList(collectElementsInBB, bblist)

Seems fine but there’s no need to ask; just run it and fix it if it doesn’t work.

@Thomas_Mahon,

True, but there is where my “drive to learn” kicks in. As a python newbie I’m trying to understand the flow and approach. Sometimes the approach might work just fine but I’m taking a long route to get there.
So if I’m trying to do 1+1=2 and I’m actually doing sqrt(100-50 divide by 2) - 3 would be “ok” but also “dumb”…

:sweat_smile:

Okay,

Final thing:

Areas within a component. … Is it possible to get the areas defined within a component?

Change the code mentioned above to OST_Areas doesn’t work obviously … but is it possible ??