Get room of stairlanding

This graph with a single Archi-Lab node works for me, which leads me to believe it’s an issue with the geometry in the Python node.

You’re getting an XYZ so my guess is scaling. I noticed you’re in metric using meters (kudos for not being on team mm), and that instead of using the geometry conversion utility you were pulling the X, Y and Z value of the point. As Dynamo converts geometry in the document units, this means you’re getting values in meters for the X, Y, and Z value. When you pull those values using point.X, point.Y and point.Z you’re going to get the value in meters, but Revit always works in feet internally. So… instead of a point at 9.4 meters, -0.8 meters, -0.1 meters (units added for clarity) you’re getting points at -9.4 feet, -0.8 feet, -0.1 feet, which is off by a wide margin.

We have some options to circumvent this in Python.

  1. Have Dynamo do the conversion for you using the ToRevitType() method. Adding something like centroids = [point.ToRevitType() for point in centroids] before your loop will do for that in your last code. Note that the unwrapping likely doesn’t serve any purpose so you could even do it in the input line by using IN[0] in place of centroids in the list comprehension.
  2. Gather the elements and collect their locations as points using the Revit API entirely, then get the room from there. This is more complex - hopefully this code self documents and informs you well enough as is:
########################################
############## Properties ##############
########################################
__author__ = 'Jacob Small'
__version__ = '0.0.1'
__description__ = """Get the room for a selection of elements by collection the location point, center of the location curve, or center of the primary solids."""
__RevitBuilds__ = "2023.1"
__DynamoBuilds__ = "2.16.0"
__ReleaseNotes__ = """Not thuroughly tested - for educational purposes"""
__Dependancies__ = "None"
__Copyright__ = "Autodesk Inc, 2024"
__License__ = """MIT"""



########################################
### Configure the Python environment ###
########################################
### standard imports ###
import sys #add the sys class to the Python environment so we can work with the sys objects
import clr #add the CLR (common language runtime) class to the Python environment so we can work with .net libraries
import math #add the Math class to the Python environment so we can do math stuff
import random #add the Random module to the Python environment so we can impersonate a squirrel

### basic Dynamo imports ###
clr.AddReference('ProtoGeometry') #add the Dynamo geometry library to the CLR
from Autodesk.DesignScript import Geometry as DG #add the Dynamo geometry class using the alias DG, to ensure no overlap between class calls in Revit or Dynamo
clr.AddReference('DSCoreNodes') #add the standard Dynamo library to the CLR
import DSCore # import the standard Dynamo classes to the Python environment
clr.AddReference('GeometryColor') #add the Geometry color library to the CLR
from Modifiers import GeometryColor #import the GeometryColor class to the Python environment

### Dynamo Revit imports ###
clr.AddReference("RevitNodes") #add Dynamo's Revit nodes library to the clr
import Revit #import Dynamo's Revit node class
clr.ImportExtensions(Revit.Elements) #add the element conversion methods to the CLR
clr.ImportExtensions(Revit.GeometryConversion) #add the geometry conversion methods to the CLR
clr.AddReference("RevitServices") #add the Revit services library to the CLR
import RevitServices #import the Revit services class to the Python environment
from RevitServices.Persistence import DocumentManager #import the document manager class to the Python environment 
from RevitServices.Transactions import TransactionManager #import the transaction manager class to the Python environment 

### Revit API imports ###
clr.AddReference("RevitAPI") #add the Revit API to the CLR
import Autodesk #add the Autodesk class to the Python environment 
from Autodesk.Revit.DB import Location, LocationCurve, LocationPoint, Options, Solid, XYZ #import the relevant classes of the Revit API to the Python environment



########################################
########### Code starts here ###########
########################################
doc = DocumentManager.Instance.CurrentDBDocument #the current Revit document
elems = UnwrapElement(IN[0]) #import the elements from IN[0] of the Dynamo environment and convert to native Revit elements
if not elems.__class__ == [].__class__ : elems = [elems] #ensure that elems is a list, not an individual object, so that we can always prepare for a loop
results = [] #list for the results

for elem in elems: #for each element
    pnt = None #set the pnt variable to null
    location = elem.get_Location() #get the location
    
    if location.__class__ == LocationCurve: #8if the location is curve based
        crv = location.Curve #get the curve
        pnt = crv.Evaluate(0.5,True) #get the midpoint of the curve
    
    elif location.__class__ == LocationPoint: #or if the location is a point
        pnt = location.Point #get the point
    
    else: #otherwise
        geometries = elem.get_Geometry(Options()) #get the default geometry
        sld = None #set the solid to as a null
        for geom in geometries: #for each geometry
            if geom.__class__ == Solid: #if the gometry is a solid
                if sld == None:#if the sld variable is still null
                    sld = geom #set the sld to the geometry
                else: 
                    sld = BooleanOperationsUtils.ExecuteBooleanOperation(sld,geom,BooleanOperationsType.Union) #otherwise union the solid with the others
                pnt = sld.ComputeCentroid() #return the centroid of the unioned solid
    
    if pnt:#if the pnt variable isn't null
        rm = doc.GetRoomAtPoint(pnt) #get the room at the point
        if rm: results.append([elem,pnt.ToPoint(),rm]) #if a room was found return the element, sample point, and room
        else: results.append([elem,pnt.ToPoint(),"No Room At The Point. Point may be between rooms - review closely." ]) #otherwise return the element, sample point, and informative message
    else: results.append([elem,None,"Location Point Not Found. Consider alternative location methods."]) #if no point was found return the element, null, and an informative message



#########################################
##### Return the results to Dynamo ######
#########################################
OUT = results

Hope this helps!

2 Likes