Automation of Typing Finishing Materials into Room Schedule

Hi everyone,

I’m new at Dynamo, and have an issue with Revit room schedules. I also asked about that in Revit forums.

I want to automate of typing finishing materials into room schedule cells. In Revit, finishing materials in schedule must be typed one by one as text or create a key schedule to make things easier. However, some projects have many different room types with many finishing material combinations.

In Dynamo, is it possible to design a graph which will be able to pick finishing materials of wall, floor and ceiling? If I could pick finishing materials (last layer of wall/floor/ceiling) for each rooms, this material information could set into room schedule cells such as wall finish, floor finish, ceiling finish.

Is there a way to get finish materials of a room?

Check the Room.Finishes node in the Clockwork package.

1 Like

Great, thanks. I tried quickly to get a material name from any room, and it worked as in the graph. Now, I must find the finishing materials for each room. Is it possible to find finishing materials from this list? If I could find them, I would set this material information into the Revit schedule.

What do you mean finishing materials?

It has detected ‘structure layer’ of the floor. I need to find the finishing material, not leveling screed, laminated parquet as in the example. It is not listed. 0 and 1 indexes in “finishMaterials List” are structure layers of 2 separate floors.

Post the dyn and a sample file and I’ll try to have a look.

I did this using SpatialElementGeometryCalculator to GetBoundaryFaceInfo of each face of a Room solid. This is probably pretty sloppy in terms of execution but it worked. I collected edge loops in order to identify which walls were different from the others (accent walls, etc.) with a Detail Item in plan.

import clr

clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager

from itertools import compress

doc = DocumentManager.Instance.CurrentDBDocument

rooms = UnwrapElement(IN[0])
scale = IN[1]

calculator = SpatialElementGeometryCalculator(doc)

elementMaterial = list()
elementMaterialID = list()
elementEdgeS = list()
elementEdgeE = list()
elementRoom = list()
elementFloor = list()
elementCeiling= list()
elementLoops= list()
rSolid = list()
normalList = list()
for room in rooms:
	results = calculator.CalculateSpatialElementGeometry(room)
	roomSolid = results.GetGeometry()
	rSolid.append(roomSolid)
	roomMaterial = list()
	roomMaterialID = list()
	ceilingMaterialID = list()
	floorMaterialID = list()
	roofMaterialID = list()
	roomEdgeS = list()
	roomEdgeE = list()
	roomLoops = list()
	normals = list()
	faceEdge = list()
	floorFace = list()
	normalZs = list()
	
	for face in roomSolid.Faces:
		for subface in results.GetBoundaryFaceInfo(face):
			boundingElement = subface.GetBoundingElementFace()
			bBox = boundingElement.GetBoundingBox()
			p=bBox.Min
			q=bBox.Max
			mid = p+.5*(q - p)
			normalFace=boundingElement.ComputeNormal(mid)
			normalZ = normalFace.Z
			normalZs.append(normalZ)
			if 0 < normalZ <= 1:
				try:
					fmaterialID = boundingElement.MaterialElementId
					floorMaterialID.append(fmaterialID)
					rmaterialID = boundingElement.MaterialElementId
					roofMaterialID.append(fmaterialID)
				except:
					x=0
			if 0 > normalZ >= -1:
				try:
					cmaterialID = boundingElement.MaterialElementId
					ceilingMaterialID.append(cmaterialID)
				except:
					x=0
			if normalZ == 0:
				try:
					materialID = boundingElement.MaterialElementId
					materialName = doc.GetElement(materialID).Name
					roomMaterialID.append(materialID)
					faceEdge=face.EdgeLoops
					loops=0
					for loop in faceEdge:
						
						for fE in loop:
							loops=loops+1
							curve = fE.AsCurve()
							p = curve.GetEndPoint(0)
							q = curve.GetEndPoint(1)
							roomLoops.append(loops)
							roomEdgeS.append(p*scale)
							roomEdgeE.append(q*scale)
				except:
					x=0
	elementRoom.append(rSolid)
	elementEdgeS.append(roomEdgeS)
	elementEdgeE.append(roomEdgeE)	
	elementMaterialID.append(roomMaterialID)
	elementFloor.append(roofMaterialID)
	elementCeiling.append(ceilingMaterialID)
	normalList.append(normalZs)
	elementLoops.append(roomLoops)
	
OUT = elementEdgeS,elementEdgeE,elementFloor,elementCeiling,elementMaterialID,elementLoops
3 Likes

I added your code into Python Script by editing. Warning occured as in the screenshot.

Hit the + icon on the Python node to add another input to the python node, then insert the resulting scale value from the view type where you would want to highlight the accent walls (try using 1/48 for 1/4” = 1’-0”, or 1/50 for similar metric scale values if you don’t know what you should use).

Alternatively you can remove the lines which refer to scale and see if that works.

1 Like

As you said, I tried on a simple file too, it’s same. I also tried to choose by element type, it could work in next steps, but it would be very difficult to set a graph for every room and finishing.

I uploaded files below.

Getting Materials.rvt (1.5 MB) Getting Materials.dyn (33.3 KB)

1 Like

Yes thanks, I set 1/100 as scale and it worked for the same simple file. I uploaded .dyn file with .rvt file.
I have a lot of lists and nested lists now. How can I find and filter room finishings? Because, quantities of items are not same, and 176 items has been listed for only 3 rooms.

Getting Materials.rvt (1.5 MB) Python.dyn (10.2 KB)

My work computer isn’t currently setup correctly to troubleshoot but, as I recall, you have to have Areas and Volumes computed for this to work. I noticed your Getting Materials file has this set to Areas only.

I’m sorry, I couldn’t understand. Do you mean .rvt file?

I edited the graph I set with Greg’s Python codes. I have 2 separate floor for each 3 rooms, concrete floor and laminate parquet flooring. I noticed that which floor is at 0.00 level, its materials have been listed as floor materials. Why did it pick floors at 0.00 level? I want to use 0.00 level for structural floors, want to add floorings over this main structural floor, separately room by room.

Getting Materials.rvt (1.5 MB) Python2.dyn (14.9 KB)

Rooms were inserted at an elevation of 0.

Double check that ‘calculate areas and volumes’ is enabled in your Revit model (looks like it isn’t).

1 Like

Thanks Jacob, I enabled ‘calculate areas and volumes’, but I didn’t understand what it fixed. In my last graph, I found materials. I think I just need to manipulate room elevation, or I will try another method.

Without that enabled Revit will only ever ‘see’ walls boundaries at the level you place the room in. This is why when you elevated the floor you get the leveling bed instead of the laminate. By turning in boundaries the room will see the finish floor, ceilings, walls, and all the rest as it ‘fills the 3D space In the model’ instead of filling the 2D plane at the level.

As long as the Room volume intersects the ceiling… by default it’s only 8ft above the level.

1 Like