Index is occupied or out of range

I’ve inherited some legacy python from a previous dev.
Fortunately, they have left a link to the original blog post that was used as a starting point.
But I think I’m hitting a syntax error in the parts they tried to modify.
Specifically at line 96 its saying index is occupied or out of range

https://learndynamo.com/mod2/

#Copyright(c) 2016 www.Learndynamo.com 
#Please contact at jeremy@learndynamo.com

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

clr.ImportExtensions(Revit.GeometryConversion)

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

doc = DocumentManager.Instance.CurrentDBDocument

toggle = IN[0]
point = 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)
	

	
		#Retrieve the mid point of model lines and get X,Y.	
	index = 0
	for modelpoint in modelPoints:	
		modelMP = modelpoint.ToXyz()
		modelMPX = modelMP.X
		modelMPY = modelMP.Y
			
			#Retrieve individual lines of crop window.		
		cropLines = cropCurves[index]
		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[index].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	
		
		combY = modelMPY-elevationPTY
		combX = modelMPX-elevationPTX			
		ang = -atan2(combX, combY)
		
		comparisonAng = round(degrees(ang))
		newAng = 90
		arrowPos = 2
		eleMarker = ElevationMarker.CreateElevationMarker(doc, viewType.Id, elevationPT, 100)
		#left arrow
		if comparisonAng >= 45 and comparisonAng <= 135:
			arrowPos = 0
			newAng = -90
		#top arrow
		#changed <= to < august 5th 2021
		if comparisonAng <= 45 and comparisonAng > -45:
			arrowPos = 1
			newAng = 0
		#bottom arrow
		if comparisonAng > 135 or comparisonAng < -135:
			arrowPos = 3
			ang = ang + radians(90)
			
		#default is right arrow
		ele = eleMarker.CreateElevation(doc, doc.ActiveView.Id, arrowPos)
		ElementTransformUtils.RotateElement(doc, eleMarker.Id, ln, ang)
		ElementTransformUtils.RotateElement(doc, eleMarker.Id, ln, radians(newAng))
		
		#ElementTransformUtils.RotateElement(doc, eleMarker.Id, ln, ang)
			#Create elevation marker and elevation in position 0.
			
			#Rotate elevation marker towars model line.
		
		#ElementTransformUtils.RotateElement(doc, eleMarker.Id, ln, math.radians(90))
			#	
		crManager = ele.GetCropRegionShapeManager()
			#crShape = crManager.GetCropRegionShape()
	
		newCurveLoop = []
		newCurveLoop.Add(l1)
		newCurveLoop.Add(l2)
		newCurveLoop.Add(l3)
		newCurveLoop.Add(l4)
				
		cLoop = CurveLoop.Create(newCurveLoop)
		index+=1

		try:			
			crManager.SetCropShape(cLoop)
			lst.append(ele)
			#lst.append("Elevation Created")
			
		except:
			pass
			lst.append("Missed Elevation")
	
		TransactionManager.Instance.TransactionTaskDone()
		
		#OUT = degrees(ang)
		OUT = lst
	
else:

	OUT = "Set toggle to TRUE"

Can you share a stripped down Revit model with the items need to run the script?

I’ve yet to try to create an Elevation via the API, but so far as I can tell this seems like it should be working. My best guess at the moment, is that ElevationMakers are built with a default direction, so the index value for that direction is inherently occupied. So when you try to create a new elevation using that index, it throws an error.
This is relatively easy to test for. Can you run this and tell me what the python node outputs?

#Copyright(c) 2016 www.Learndynamo.com 
#Please contact at jeremy@learndynamo.com

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

clr.ImportExtensions(Revit.GeometryConversion)

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

doc = DocumentManager.Instance.CurrentDBDocument

toggle = IN[0]
point = 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)
	

	
		#Retrieve the mid point of model lines and get X,Y.	
	index = 0
	for modelpoint in modelPoints:	
		modelMP = modelpoint.ToXyz()
		modelMPX = modelMP.X
		modelMPY = modelMP.Y
			
			#Retrieve individual lines of crop window.		
		cropLines = cropCurves[index]
		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[index].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	
		
		combY = modelMPY-elevationPTY
		combX = modelMPX-elevationPTX			
		ang = -atan2(combX, combY)
		
		comparisonAng = round(degrees(ang))
		newAng = 90
		arrowPos = 2
		eleMarker = ElevationMarker.CreateElevationMarker(doc, viewType.Id, elevationPT, 100)
		
		OUT = eleMarker.HasElevations(), [eleMarker.IsAvailableIndex(x) for x in range(4)]
	
else:

	OUT = "Set toggle to TRUE"

@stewart.skyler
I think that would support your hypothesis, no?
So I guess my next step is trying to figure out how to over write the default value of the elevation marker?

Huh. Yes and no, I was anticipating that first result to be true as well, if any of the items in the following list were. The thought being that it’s creating a default elevation and that’s why one of the indices is unavailable.

Taking another look, maybe ElevationMarkers can hold view types other than elevations, and your variable viewType holds a View Type other than an elevation. If you swap eleMarker.HasElevations() with eleMarker.CurrentViewCount does that come up with a number larger than 0?

If this is the case then yeah, I think the next step would be to check if the index is in use, and if so delete that view and create a new one.
I don’t see a convenient way to retrieve that via it’s members in the API docs.
But what might work is using a FilteredElementCollector with an ElementWorksetFilter.

fil = FilteredElementCollector(doc)
workset_filter = ElementWorksetFilter(eleMarker.WorksetId)
views = fil.OfClass(View).WherePasses(workset_filter).ToElements()

Note that I haven’t tested that bit of code, but I think it should work.

Edit:
Slight change to the FilterdElementCollector so that it only returns views.

1 Like

thanks again, I’ll try it and see what happens

1 Like

as far as minimal model, the original blog post just uses a loop of model lines. I’ve added a wall with some windows, because the elevations looked really bland. Then I added a loop of curtain walls, because I know in the end that’s what I’m working toward.

I’ll see if I can get a basic version of the core graph too
I’ve been digesting it by the sections from his original writing

ModuleTwo.rvt (5.0 MB)