Finding a room by wall

Finding a room by wall

Anonymous
Not applicable
3,280 Views
11 Replies
Message 1 of 12

Finding a room by wall

Anonymous
Not applicable

Hello.

 

If you look at the image, there is a red wall and there are rooms up and down.

Can you find rooms with walls?

 

wallandroom.jpg

 

What function should I use and how should I access it?

 

var walls = new FilteredElementCollector(document)
                .WhereElementIsNotElementType()
                .OfCategory(BuiltInCategory.OST_Walls)
                .OfClass(typeof(Wall))  
                .Cast<Wall>()
                .Where(x => x.LevelId.Equals(level.Id));


foreach (var wall in walls)
{
    if (wall.Id.ToString().Equals("3359963"))//wall Id
    {
        var element = document.GetElement(wall.Id);
        var parameter = element.get_Parameter(BuiltInParameter.WALL_ATTR_ROOM_BOUNDING);  // 1 bounding, 0 no bounding
        var value = parameter.AsValueString();
        ;

    }
}

I tried, but I have no idea.

Thanks.

0 Likes
Accepted solutions (1)
3,281 Views
11 Replies
Replies (11)
Message 2 of 12

jeremy_tammik
Alumni
Alumni

Retrieve the wall location line. In the middle of the location line, determine a perpendicular point P about the wall width away from the location line. Use the IsPointInRoom method on that point:

 

https://www.revitapidocs.com/2021.1/96e29ddf-d6dc-0c40-b036-035c5001b996.htm

 

No, better use the GetRoomAtPoint method:

 

https://www.revitapidocs.com/2021.1/656d34c2-1e53-7278-ab83-fefaff7f40a4.htm

 

Note that you will have different walls on the right and left. Which one do you want?

 

Also note that you can have any number of rooms along one asingle wall. Again, which one are you after?

  

You might want to read more about 2D Booleans and Adjacent Areas:

 

https://thebuildingcoder.typepad.com/blog/about-the-author.html#5.2

    

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 3 of 12

architect.bim
Collaborator
Collaborator

Hi! I think there is no out-of-the-box method to do it. But you can make it yourself. You can try the following:

  • variant 1: get wall core face, create normal to that face as XYZ object and pass it to IsPointInRoom method to identify first neighboring room; repeat the same with the opposite direction vector to get second room;
  • variant 2: open transaction, insert temporary door in wall, get its FromRoom and ToRoom prorerties, rollback transaction to delete temporary door.

I am sure there are other several variants to perform this task.

Good luck!


Maxim Stepannikov | Architect, BIM Manager, Instructor
Message 4 of 12

SergeyShvydko
Advocate
Advocate
Accepted solution

Hello

May be this class BoundingBoxIntersectsFilter will help you

It helps me to solve a similar problem. Look at the example below  

def get_rooms(wall):
    document = wall.Document
    wall_bb = wall.get_BoundingBox(None)
    outline = Outline(wall_bb.Min, wall_bb.Max)
    bbfilter = BoundingBoxIntersectsFilter(outline)
    rooms = FilteredElementCollector(document).OfCategory(BuiltInCategory.OST_Rooms).\
        WherePasses(bbfilter).ToElements()
    return rooms

 



Sergey Shvydko
Architect, BIM-Manager
Курс по Revit Architecture
t.me/sshvydko




Message 5 of 12

jeremy_tammik
Alumni
Alumni

Nice. I was not aware the a bounding box intersection filter would honour rooms and their bounding boxes. Very useful indeed.

 

Please note that you could skip the call to ToElements and just return the filtered element collector directly.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 6 of 12

Anonymous
Not applicable

Hello.

 

This is the best for me.
The bounding box and the filter in the room are amazing.

 

Thanks.

0 Likes
Message 7 of 12

Anonymous
Not applicable

Excuse me. Check this post?


I thought this solution was good, but I ran into a big problem.

In that case, like my image, it works perfectly.However, if the wall is diagonal, the meaning of the bounding box disappears.

 

I tried using a solid filter but it didn't work.

Also, it seems impossible to have a bounding box for the curved wall.

 

Do you have any good ideas?

Thanks.

0 Likes
Message 8 of 12

jeremy_tammik
Alumni
Alumni

Yes, the bounding box is always axis aligned.

 

You can use that as a first rough check. The bounding box filter is a quick filter, which is important:

 

http://thebuildingcoder.typepad.com/blog/2015/12/quick-slow-and-linq-element-filtering.html

 

For more precision further down the road, you can use an element intersection or solid intersection filter. They are slow filters.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 9 of 12

Anonymous
Not applicable

I don't care if I use a slow filter.

But even if I use the solid intersection filter I can't get the value.


I saw it in some post. Solid filters are not detected as intersecting elements that are automatically joined.

So, if you find the solid of the wall and apply the solid filter to find the room, the value does not come out.


On the other hand, the bounding box intersection filter is evaluated.

Only the difference between the filters is different.

 

Is there an element intersection filter? I couldn't find it.

This is the best if it is obtained as the intersection of the wall and the room.

0 Likes
Message 10 of 12

jeremy_tammik
Alumni
Alumni

The element intersection filter is named ElementIntersectsElementFilter:

 

https://www.revitapidocs.com/2021.1/7e54ea68-559b-b449-1d4f-619c4e07f077.htm

  

How strange that you could not find it.

  

I know that it works with a wall. I do not know whether it will work with a room. I will be interested to hear what you discover on that front. 

  

Otherwise, to use a solid intersection filter with the room, you may be able create the filter from the room's closed shell, if that returns a solid:

  

https://www.revitapidocs.com/2021.1/1a510aef-63f6-4d32-c0ff-a8071f5e23b8.htm

  

Otherwise, you might be able to query the room for its boundary segments closed loop and use that to create a vertical extrusion solid.

  

However, for complex adjacency analysis of rooms with vertical walls, I would always prefer to reduce the analysis to a two dimensional problem in the XY plane and use a 2D Boolean library to determine the required relationships.

 

That will give you more analysis functionality with less effort:

 

https://thebuildingcoder.typepad.com/blog/about-the-author.html#5.2

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 11 of 12

Anonymous
Not applicable

Thanks.

But my standards are different. I want to find a room by wall.
What you suggest is to find the walls through the room.

It's the opposite of me. Right?

 

This is the post I found. Please check.

https://forums.autodesk.com/t5/revit-api-forum/questions-about-elementintersectssolidfilter/td-p/753...

 

And the same goes for using ElementIntersectsElementFilter. Can't find connected room.

 

 

// In this case, the axis is perfect. Diagonal can't.
var neighborRoom = new FilteredElementCollector(Document).OfCategory(BuiltInCategory.OST_Rooms)
.WherePasses(wallBoundingBoxIntersectfilter)
.Cast<Room>()
.ToList();

//If I chose the wall
//test1 :Check the room values ​​in the document.
var test1 = new FilteredElementCollector(Document).OfCategory(BuiltInCategory.OST_Rooms).ToList();

// test2 :When I put a filter on the selected wall, the result is only the  joined walls, and the room could not be found. 
var test2 = new FilteredElementCollector(Document).WherePasses(new ElementIntersectsElementFilter(SelectedWall)).ToList();

// test3 :The result list is 0
var test3 = new FilteredElementCollector(Document).OfCategory(BuiltInCategory.OST_Rooms).WherePasses(new ElementIntersectsElementFilter(SelectedWall)).ToList();


var solids = GetSolids(SelectedWall);
if (solids.Count > 0)
{
  foreach (var solid in solids)
  {
// test 4: Other types of insersects were checked, but Room did not exist.
// result list : panel, wall, structure...
   var test4 = new FilteredElementCollector(Document).WherePasses(new 
    ElementIntersectsSolidFilter(solid)).ToList();
// test 5: Therefore, the list of values ​​is 0
   var test5 = new FilteredElementCollector(Document).OfCategory(BuiltInCategory.OST_Rooms).WherePasses(new ElementIntersectsSolidFilter(solid)).ToList();
  }
}

 

 

When looking for walls by room, I already found using GetBoundarySegments.

However, in the opposite case, diagonal coordinates, filtering, etc. I cannot currently find.

 

 

0 Likes
Message 12 of 12

rhanzlick
Advocate
Advocate

I see this is marked as solved, but I would utilize RoomBoundarySegments. For each room, access elementIds (bonus: or LinkElementId!) of boundary segments, and check if the list contains your ReferenceWall's ElementId. I could think of a few examples where boundary segments may be slightly buggy here, but almost any other method is preferable (in terms of accuracy, not necessarily robustness) than utilizing boundingboxes IMHO.