Announcements
Autodesk Community will be read-only between April 26 and April 27 as we complete essential maintenance. We will remove this banner once completed. Thanks for your understanding
Announcements
We are currently migrating data within this board to improve the community. During this process, posting, replying, editing and other features are temporarily disabled. We sincerely apologize for any inconvenience caused and appreciate your understanding. Thank you for your patience and support.

Get the walls, ceiling and floor of a room?

Samuel.Arsenault-Brassard
Advocate Advocate
8,704 Views
16 Replies
Message 1 of 17

Get the walls, ceiling and floor of a room?

Samuel.Arsenault-Brassard
Advocate
Advocate

I've been able to get a list of all the elements that are in a room, but I am not able to figure out how to automatically obtain the walls, ceiling and floor that are associated with these rooms.

 

Is this information possible through the API?

 

And yes, I do understand that a wall, floor and ceiling may have a relationship with multiple rooms, not just one

Reply
Reply
0 Likes
Accepted solutions (1)
8,705 Views
16 Replies
Replies (16)
Message 2 of 17

Yien_Chao
Advisor
Advisor
Reply
Reply
Message 3 of 17

Yien_Chao
Advisor
Advisor

a simple boundingbox filter and a multicategory filter.. and voila!

 

2020-12-04_15-57-11.jpg

Reply
Reply
Message 4 of 17

Samuel.Arsenault-Brassard
Advocate
Advocate

One last question, is the bounding box actually a square box? I am wondering if it will capture rogue elements if the room is not square, for example a serpentine corridor.

 

BoundingBox.jpg

Reply
Reply
0 Likes
Message 5 of 17

jeremytammik
Autodesk
Autodesk

The bounding box is always a rectangular box, or, more precisely, a rectangular cuboid, with X, Y and Z axis-aligned faces.

   



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Reply
Reply
0 Likes
Message 6 of 17

Yien_Chao
Advisor
Advisor

i dont think so... 

 

https://www.revitapidocs.com/2020/3c452286-57b1-40e2-2795-c90bff1fcec2.htm

 

A three-dimensional rectangular box at ...

 

Reply
Reply
0 Likes
Message 7 of 17

Samuel.Arsenault-Brassard
Advocate
Advocate

So, it would create a problem for a non-rectangular room right? (trying to detect related walls, floors and ceilings of a room)

Reply
Reply
0 Likes
Message 8 of 17

Yien_Chao
Advisor
Advisor

i would try different approach to that.

try to use IsPointInRoom() instead? https://www.revitapidocs.com/2020/96e29ddf-d6dc-0c40-b036-035c5001b996.htm

 

for ceiling , wall and floor, you can just take the center points and project the points to room.

 

hope that may help.

Reply
Reply
0 Likes
Message 9 of 17

Samuel.Arsenault-Brassard
Advocate
Advocate

"project the points to room." I'm not sure I understand this part. I guess you can draw a line from the centroid of the room to the centroid of the walls?

 

The inherent problem I see is that the centroid of each wall/floor/ceiling is going to be outside each room since it is its shell. It's almost like we need to offset each room's volume to encompass the centroids of its shells.

 

WallMiddle.jpg

Reply
Reply
0 Likes
Message 10 of 17

Typo:

blue line = extent of *room*

Reply
Reply
0 Likes
Message 11 of 17

Yien_Chao
Advisor
Advisor
Accepted solution

example : choose center face of wall, then project the point according to normal by . Then use the isinroom() for each point, you should have 2 rooms for a single wall.

 

easier with ceilings and floor finishes.

 

 

Reply
Reply
0 Likes
Message 12 of 17

Samuel.Arsenault-Brassard
Advocate
Advocate

Interesting.

 

I can imagine lots of problems with this approach like a corridor that borders 20 rooms will only detect one room on each sides.

Same with a floor or ceiling being shared by multiple rooms. Especially if the designers were lazy and modeled the floors/ceilings to go through walls.

 

It's a very interesting problem, I will keep pondering on it. I'm actually surprised there's no direct way to do this directly in the API or in Revit schedules. Feels like every walls should know what rooms acost them and all rooms should know what surfaces bound them.

Reply
Reply
0 Likes
Message 13 of 17

Yien_Chao
Advisor
Advisor

i think you can start another thread on the particuliar topic.

In the meantime, , i think the first question has been resolve.

Reply
Reply
0 Likes
Message 14 of 17

mastjaso
Advocate
Advocate

I've been down this road before and it depends on what precisely you're trying to do with the walls, and whether you need interior walls etc.

 

Just Exterior Bounding Walls:
If you just need the exterior walls of the room, then the simplest method is to use the GetBoundarySegments method. Every room, space, and area in Revit inherits from the SpatialElement class which has this method, and will return a list of RoomBoundarySegments, each one containing the curve segment, and what element is creating it (wall, room boundary line, etc.). This will solve that whole wall centroid being outside of the room problem.

It's probably worth noting that this method will not work in precise situations with linked files, a bug I documented here. I haven't tested it since then but I would be very surprised if Revit actually fixed it since so it's worth watching out for. 

 

All Walls Including Non Bounding Interior Walls:
Otherwise if you need walls that are non bounding and interior to the room, I found that in general, all of Revit's projection methods are somewhat slow (and algorithms using them often have edge cases that might be missed), but like others have said, I found both the BoundingBoxIntersector and the isPointInRoom methods to be very fast and performative. To get *all* of the walls associated with a room, including interior ones, I would first use the boundary segments method to get the bounding walls / walls that won't be *inside* the room. Then, use the bounding box intersector filter to get all the walls in the model that intersect your room (like you said, bounding boxes are rectangular and don't rotate so this will be rough and pick up walls from other rooms). Set aside the walls that you already know are the boundaries, then for the rest, check the coordinates of the end point and midpoint of each wall segment, to see if any of those points are in the room with the isPointInRoom method. If one of them is then that wall cuts through the interior of the room. 

I believe the only situation that this might miss, is if you had a room that was bounded by room boundary lines, and a super long non-bounding wall cut entirely through the room without any end points or midpoints landing within the room. 


Floors And Ceilings:
Getting the floors and ceiling are somewhat more complicated and I believe will likely necessitate projection if you want to be able to capture every bulk head / potential split level etc. What I would do is start with your room's bounding box. Then generate a grid of points with even spacing inside this box (maybe 0.5 - 1ft apart), halfway between the top and bottom. Test each point with the isPointInRoom method, and discard the ones that aren't. You'll now have an irregular grid of points all located within the bounds of your room. Now for each point project a ray upwards and one downwards and capture any floors or ceilings that they intersect before leaving your room bounds. This should reliably capture every single floor and ceiling associated with a room, and if it is missing any, you can just increase the resolution of your point grid. 

Reply
Reply
Message 15 of 17

jeremy_tammik
Autodesk
Autodesk

Thank you very much for your experienced advice.

 

I shared it here on the blog for posterity:

 

https://thebuildingcoder.typepad.com/blog/2021/03/boundary-elements-and-stirrup-constraints.html#3

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Reply
Reply
0 Likes
Message 16 of 17

634914927
Participant
Participant
果然厉害!
Reply
Reply
Message 17 of 17

rhanzlick
Advocate
Advocate

To answer the initial question @mastjaso has given an answer very close to what I would recommend. That is, three different methods that will, when combined, find all content requested:


  1. To obtain walls: spatialElement.GetBoundarySegments() should do what you want for walls who's RoomBounding parameter is set to be checked.
  2. To obtain ceilings and floors, I have used a couple of different methods in the past with varying success:
    1. Use a reference intersector from your spatialelement's location point, filtered by category ceilings/floors - this process can be somewhat slow, and as @mastjaso mentioned, you may want to do it in a grid so as not to miss smaller segments or pieces
    2. You can check some point-based representation of your ceiling or floor (whether that be center-of-mass, or all edge points, etc) using the IsPointInRoom method. I use that method in MANY MANY instances and it is very helpful.
  3. **Finally** one additional method is to ensure that your rooms Unbounded Height is set at least as high as your ceiling height, and obtain the solid from your spatial element using ClosedShell. Using solids you can check for solid intersections between the spatial element closed shell and solids from walls/floors/ceilings in your project. This would be the most generalized as it wouldn't matter if they are roombounding or not. This would certainly benefit from some prefiltering using phases, levels, etc. Good Luck, and feel free to follow up with any code samples if you find something else useful!

 

Reply
Reply
0 Likes