Get rooms within element


#1

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)).


#2

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.


#3

@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)

#4

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


#5

@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:


#6

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 ??