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

For Revit 2020.2 and Dynamo 2.3.0;

Hi everyone. This graph includes Clockwork and archilab nodes. Thanks to them, I had to only create kinds of filters for walls, floors, ceilings and roofs. Other elements such as, columns, beams are excluded.

Before running it, “Areas and Volumes” must be selected to find exact room boundaries (check Area and Volume Computations in Revit). By doing this, possible problems with floor and ceiling finishes will be prevented. Some problems may arise if there are stacked walls in models. In general, if lower part of these stacked walls/walls are thicker than upper part causes of this kind of problem. Finishes of upper part cannot be gathered and written. It is all about room boundaries.

You don’t have to designate finish layer (Finish 1 [4] or Finish 2 [5]) for model elements in Type Properties. If model elements consist of only structural parts , materials of these parts are written as finishes.

If same kind of elements in a same room have different materials, these materials are written to the room schedule with designated seperator string. For instance, plaster and tile are finishes of walls in a room, in room schedule wall finish will be written as Plaster “and” Tile or etc. Instead of “and” + sign may be used.

If there is no finish in a room (that means no walls, no roofs no ceilings) , hypen (-) will be written to proper cells on room schedule. It may be used for shafts that have no ceilings and floors.

I tested the graph on the simple residential building. If you encounter any problem please let me know.