Segregating Walls Based on Direction for Paint Area Calculation

Hi Folks,

I am trying to achieve the segregation of walls based on their directions to determine paint areas for room in each direction. I’ve managed to get the total paint area and the surfaces but I am stuck at segregating these surfaces with respect to the direction.

@john_pierson Rhythm’s Walls.Direction node gives the correct orientation for walls when those are drawn correctly. However, it doesn’t work as expected for copied walls and common walls between two rooms.

To clarify, I need to identify which walls (or surfaces) are facing North, South, East and West for the room. Here’s what I’ve done so far

This is how I want to segregate.

this topic is similar to what I need but it doesn’t have any references:Get surface area by orientation per room - #3 by A.Gendron

Do you need any wall type/instance information or just the geometry? I find it’s often easier to use the Room surfaces rather than the Wall surfaces for this information. That would allow you to quickly link Rooms to their unique bounding surfaces and then get their orientation relative to the room.

Surfaces are good for me, and I have already captured the surfaces I need for each room. However, I want to know which surfaces are in the North and other directions. Then I will extract a schedule to show how much interior paint is required for each direction in a particular room. Segregating surfaces is a bit challenging for me, and actually, the geometry part is all challenging for me.

Walls in each direction can have a different type of interior finish. The information on which finish should be applied to the north, south, east, or west wall is already available in four parameters for each room, provided by the design partner.

I have one more question to @Nick_Boyts : when the wall is in a linked model, I can only work with room surfaces, I believe. In that case, how can I subtract the door, window, and curtain panel areas from the room surface?

This is probably reason enough to stick with Walls since the Room won’t have that information (unless you apply it to a Room key schedule…). I find room geometry easier only when there’s no other information from the bounding elements that’s required.

You can get all the same information from linked Walls. If you do decide to go with Room surfaces for any reason though, you would essentially have to apply the same logic to your other elements to get the area of doors, windows, curtain walls, etc. and their orientation to subtract from the “wall” area. You could also try a geometry intersection with the surface, but that could end up being more tedious.

Relative to what? Relative to the room or the building? If you’re looking for directions relative to the room then you can just get the center of the room and vectors to each of the walls to get the relative orientation. If you’re wanting it relative to the building then how are you determining the north “half” or the east “half”? If you know where the break is you can apply the same vector logic to get relative directionality.

For walls that are in linked models I am getting the Model Curve Element. and in some cases Revit Link Instance. This part is is tricky for me.

I did managed to segregate walls in host model based on their direction with respect to room when I connected room curve instead of Wall curve to Curve.NormalAtParamater.

Where are you stuck now? It seems like you were able to get at least partially what you wanted from the room curves. What’s the next step?

I am stuck at this point

When walls are in a linked model, I can’t get those walls for intersection with the room.

My code currently filters out rooms whose boundary segments do not refer to any wall. It also filters out those boundary segments which refer to anything other than walls.

all_rooms = [room for room in FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType() if room.Area!=0]

options = SpatialElementBoundaryOptions()
boundloc = AreaVolumeSettings.GetAreaVolumeSettings(doc).GetSpatialElementBoundaryLocation(SpatialElementType.Room)
options.SpatialElementBoundaryLocation = boundloc

room_ids = set()
filtered_rooms = []
for room in all_rooms:
	if room.GetBoundarySegments(options):
		for seg in room.GetBoundarySegments(options)[0]:
			element = doc.GetElement(seg.ElementId)
			if element is not None and "Wall" in element.GetType().ToString():
				if room.Id.IntegerValue not in room_ids:
					filtered_rooms.append(room)
					room_ids.add(room.Id.IntegerValue)
					break

walls = []
walls_curve = []
for room in filtered_rooms:
	ids = set()
	unique_walls = []
	unique_walls_curve = []
	if room.GetBoundarySegments(options):
		for seg in room.GetBoundarySegments(options)[0]:
			if doc.GetElement(seg.ElementId) is not None and "Wall" in doc.GetElement(seg.ElementId).GetType().ToString():
				if seg.ElementId.IntegerValue not in ids:
					unique_walls.append(doc.GetElement(seg.ElementId))
					unique_walls_curve.append(seg.GetCurve().ToProtoType())
					ids.add(seg.ElementId.IntegerValue)
		walls.append(unique_walls)
		walls_curve.append(unique_walls_curve)
	else:
		walls.append(None)
		walls_curve(unique_walls_curve)

OUT = filtered_rooms,walls, walls_curve

However, when a room is surrounded by linked walls, it doesn’t give me those walls. What changes do I need to make so it gives me the walls from the linked model instead of ModelCurve Element and RevitLinkInstance Element?

If the wall is a linked element then it won’t be found in the active document. You would have to get it from the linked document. Typically you would want to know whether you’re dealing with a linked object first, but you can try using a try loop to check for the element in the active document first and then in the linked document if it’s not local. That could be problematic if you have duplicate Ids though.

The other problem you might have is that Revit tends to track the local bounding object (Link Instance) over the linked element (Wall) when bounding spaces in the model.