Get room in 3D view

I am trying to get the room that is ‘visible’ within a 3D view. Since rooms aren’t actually visible in 3D views, ‘All Elements in Active View’ only returns the walls.

Normally as a workaround, I would use the view’s naming convention as a way to ‘pair’ the view and the room. But I’m wondering if there is a better way via the API. Any suggestions?

If the view is centred on the room, and you know the lowest visible level or thereabouts I guess you could shoot a ray from the viewing position towards the level plane in the view direction and use Point in Room check on the resulting point.

Guessing you’re trying to put together a room layout sheet view and sheet’em’up workflow here that can return to views after runs and know if it doesn’t need to recreate them?

I’ve been devving this up in pyRevit for a while where I work and ended up landing on view naming convention as users can use View Title on Sheet (and yes, people ‘fix’ the names from time to time… pebkac is unavoidable. I settled on forced unique view naming as more powerful than a parameter value which can vary/duplicate itself). List comprehending out all view names proved a lot quicker than running a function for parameter/value getting as well when at large scale I found, when checking new names vs existing or indexing for a match.

For Sheets you can set a parameter more safely, as for views it’s not safe if the template can wipe out the view parameter later. Might be handy pointers if you’re going down the same path.

That method might work if you only wanted to get a single room, but if there is more than one room, then it wouldn’t work.

Another method is getting all the rooms in the model and their bounding (wall) elements and then trying to matchup the elements visible in the view. But it isn’t every elegant and probably prone to errors.

1 Like

The entire model is visible in a 3d view and a room is a 3D element. You could use a FilteredElementCollector with the View.Id overload but its slow. If you have multiple 3d views that are cropped and you’re interest only in elements within the crop then you’ll need to get the crop volume and perform intersection checks. Alternatively, if your 3D views can be mapped to plan views, then you can use the Rooms host level to get the plan view and establish visibility in the corresponding 3D view.

Might be easiest to get all rooms in the model, pull the location point, and filter out any rooms where the location point is outside of the section box.

This is not correct. Yes the room is a 3D elements but it isn’t visible in a 3D view as far as I know. If you have found a way to achieve this, then please let me know.

FilteredElementCollector with a View.Id has the same limitation as far as I can tell, i.e. no rooms will be returned.

I think @jacob.small idea is valid but thinking about it some more it is still error prone from a user’s persepective. Mostly, it relies on the view having no other rooms within the section box. This may not be the case. While the view naming convention method is also prone to errors, it would appear that it is the best option as it avoids any geometric options.

I can’t recall if Section Box geometry/bounding box is retrievable. I’m a bit too used to using Scope Boxes.

If Section Box geometry is retrievable, you can Geometry.Intersect against the Room geometries in the project, get the Solid.Volume of the intersects, and poll for the largest value. That would give you the room which occupies the most space within the Section box constraints, which presumably is the room you’re associating to that specific view.

You’re right - must have been the get_Geometry(view) method that got the better of me as it can accept a 3d view to extract room geometry.

Ok there is a very buggy way of doing this, but you’re no doubt going to be reporting this one to the Revit devs: VisibleInViewFilter(). Its really inconsistent; I’ve not found a way to get it to work reliably - seems to give a result if you set the upper level of the rooms it while Dynamo is running but not if set before?

viewFilter = VisibleInViewFilter(doc, view3d.Id)

rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WherePasses(viewFilter).WhereElementIsNotElementType();

  1. Changing views seems to reset the filter??
  2. Modifying the Limit Offset of the room kickstarts the filter with inconsistent results - either it works or it wont??
1 Like

Wouldn’t all options relying on what is visible in the view other than manually naming have the same issue?

My gut says that there is a better way to do this if approached two steps earlier in the process (ie: make the view, name the view, crop the view, lock the view, and set a parameter value of the view to use for tracking in the same process), but without the end goal stated it’s hard know either way.

Parameter value is rough as people inevitably make view templates, apply them and wipe the values. So far I’ve found naming syntax is the key. I tack the Id on with brackets and a _ separator before it, then use rsplit in Python to relate back to the rooms. If users grumble about wanting to change view names on the sheet, Title on Sheet - too easy!

Sheets luckily are more flexible and cant have values locked down, so parameters suit better there.

Hi,

Seems like one possible solution would be to take a section box and from it create a SectionView in the model, get the Rooms/Spaces that are in that view, get the data out, delete the SectionView.

Seems like not the cleanest solution but possible.
Trying to make it here to try, but having issues with Section View creation in Dynamo with Min, Max points and CS. If you just take the bounding box and plug it in, it creates a section that is more like a floorplan and it cretes it in the wrong location.

Finalized the workflow mentioned above and than figured out that you cannot see a space or room in a section view if it is not cut, so it isn’t reliable.

Posting the file here so someone maybe improves upon it.

It take the Section box, turns it into a cuboid, gets vertical surfaces and than treats it like a wall from there to create a section on the surface.

This workflow seems useful for other things but guess not for this haha.


RoomLookUpBySection.dyn (92.5 KB)