Module 2 - Unwrapped Elevations help

Hi all, I’ve been working through the often-quoted Module 2 to generate elevations of all room boundaries, but I’m running into issues with the Python code. By the looks of the comments, I’m not the only one, and I’m not getting responses to those comments (I expect due to the thread being very old now!), so is someone able to offer any assistance?

I’m getting a “no attribute ‘ToXYZ’ error in the second Python Script (line 46).

I’m using Revit 2023.1, Dynamo 2.16, I’m wondering if that is causing issue?

I could guess at the why, but would be better off for you to post what you have now, or try the following.

Comment out all lines from the itm.ToXYZ() line and below. Then add the line OUT = dir(itm).

Note that itm is the variable name you currently are failing to convert to an XYZ.

1 Like

LearnDynamo_Module_2.dyn (92.1 KB)

This is a fresh download of the Module 2 script.
I tried drawing some model lines in a new project, and selecting them with the first node.
It now creates a single elevation, but doesn’t appear to be able to iterate through the lines?

LearnDynamo_Module_2 TEST.dyn (96.7 KB)
This is my variation where I get the room boundaries instead of model lines.
This is the script that throws up the toXYZ error

Away from the PC and don’t have Revit for the day, can you post the Python code directly and flag the line which is causing the issue?

Offhand as a guess it could be that you need ToXyz() intead of ToXYZ().

1 Like

Hi @dan.buckingham

check yours inputs (specially the levels of list)

here you have a list of point instead of a point

2 Likes
import clr
clr.AddReference('RevitAPI')
clr.AddReference("RevitServices")
clr.AddReference("RevitNodes")
import RevitServices
import Revit
import Autodesk
from Autodesk.Revit.DB import *
from math import *

clr.ImportExtensions(Revit.GeometryConversion)

from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

toggle = IN[0]
points = UnwrapElement(IN[1])
modelPoints = UnwrapElement(IN[2])
cropCurves = UnwrapElement(IN[3])
viewType = UnwrapElement(IN[4])

lst = []

#Get Family View Type
vft = 0
collector = FilteredElementCollector(doc).OfClass(ViewFamilyType).ToElements()

#eleViews = []
for i in collector:
	if i.ViewFamily == ViewFamily.Elevation:		
		vft = i.Id
		break
 
if toggle == True:
	
	TransactionManager.Instance.EnsureInTransaction(doc)
	
	for ind, point in enumerate(points):
	
		#Retrieve the mid point of model lines and get X,Y.		
		modelMP = modelPoints[ind].ToXyz()
		modelMPX = modelMP.X
		modelMPY = modelMP.Y
		
		#Retrieve individual lines of crop window.		
		cropLines = cropCurves[ind]
		l1 = cropLines[0].ToRevitType()
		l2 = cropLines[1].ToRevitType()
		l3 = cropLines[2].ToRevitType()
		l4 = cropLines[3].ToRevitType()
					
		# Create a line in the z-Axis for elevation marker to rotate around.			
		elevationPT = point.ToXyz()
		elptRotate = XYZ(elevationPT.X, elevationPT.Y, elevationPT.Z+100)
		ln = Line.CreateBound(elevationPT, elptRotate)

		#Calculate the angle between Model Mid Point and Elevation Point.
		elevationPTY = elevationPT.Y
		elevationPTX = elevationPT.X							
		combY = elevationPTY-modelMPY
		combX = elevationPTX-modelMPX			
		ang = atan2(combY, combX)

		#Create elevation marker and elevation in position 0.
		eleMarker = ElevationMarker.CreateElevationMarker(doc, viewType.Id, elevationPT, 100)
		ele = eleMarker.CreateElevation(doc, doc.ActiveView.Id , 0)
		
		#Rotate elevation marker towars model line.
		ElementTransformUtils.RotateElement(doc, eleMarker.Id, ln, ang)
		
		#	
		crManager = ele.GetCropRegionShapeManager()
		#crShape = crManager.GetCropRegionShape()

		newCurveLoop = []
		newCurveLoop.Add(l1)
		newCurveLoop.Add(l2)
		newCurveLoop.Add(l3)
		newCurveLoop.Add(l4)
			
		cLoop = CurveLoop.Create(newCurveLoop)

		try:			
			crManager.SetCropRegionShape(cLoop)
			lst.append("Elevation Created")
		
		except:
			pass
			lst.append("Missed Elevation")

	TransactionManager.Instance.TransactionTaskDone()
	
	OUT = lst
	
else:

	OUT = "Set toggle to TRUE"

Since the python node doesn’t allow for the option to use levels, I’ve tried flattening lists at various points in the script, to no avail.

When modifying a graph that utilizes Python code it’s important to review the list structure as you go. Notice that the original code works with a flat list of curve elements, but you’re returning a 2D list of curves. If you flatten that list the code will work fine.

In related news, if you really want to move to a ‘elevations by room’ method I recommend you transition to creating a plane for each elevation and intersect that with the solid geometry of the room when defining your crop as this will allow instantly outlining the elevation’s cut lines at creation.

Thanks both, I’ve tried flattening at a few different points but I’m not getting the result I expect.

This seems well beyond my level, so looks like I’ll have to park this workflow for now.