Inputting a Line into Python Script Error

Wizards, I am back for more of your assistance. I am still in process of transitioning previous scripts to accommodate the new Analytical Load requirements in 2025. I have tried updating the script and thought i had it figured out, but am not getting it to work. Can someone tell me what i am missing?

Here is the error i am receiving from the Python:
Line Load Error
Here are nodes being inputted: (I dont think any of those are the issue):


Here is the current Python Script i have inputted:

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

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

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

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

doc = DocumentManager.Instance.CurrentDBDocument

host_id_value = IN[0]
curve_new = IN[1]
force = IN[2]
moment = IN[3]
LLType = UnwrapElement(IN[4])

loads = []

TransactionManager.Instance.EnsureInTransaction(doc)
for host_id_value,curve_new,force,moment,LLType in zip(host_id_value,curve_new,force,moment,LLType):
    new_load = LineLoad.Create(doc,ElementId(host_id_value),Curve(curve_new),force.ToXyz(),moment.ToXyz(),LLType)
   
TransactionManager.Instance.TransactionTaskDone()
OUT = loads

Thank you all as always for the help!

Isn’t this the same as your previous topic? If so please maintain that thread rather than starting duplicate ones: Line Load, Point Load API changes in REVIT 2025 - #17 by dweber12

Either way for more direct help you need to post a sample rvt (or indicate a simple thing to add in order to make the graph run in a Autodesk provided template), and your .dyn to reproduce the issue there so that others can reproduce and review. Currently you’re asking us to build both the .rvt and the .dyn. As an example if I wanted to build Python code to help you I’d have to understand how you generated those integers for IN[0]. And the lines for IN[1]. And the loads for IN[2]. And understand what the moment is for IN[3]. And so on. This turns what would be a 5 minute process to start helping you (download the files, open them, run the graph and start to edit) into a much longer process which can take hours (open Revit, guess at the model elements required to reproduce, guess at the Dynamo method(s) used to generate the inputs, attempt to run the code and hope we get your error).

By using a base template with just an Autodesk provided family instance or two and simplifying the incoming .dyn no IP is being uploaded so there are no concerns there.

1 Like

No this is a completely different issue and not sure how the point load question got tied into this. Secondly, the graph in which the final data is produced from is massive. It pulls information from detail components, excel files, as well as some items from a linked model. Everything works except up to the end.

@dweber12

You need to start by learning the basics of Python programming, otherwise you’ll always be stuck with the basics.

2 Likes

I have been practicing and watching videos all day and thought i had this figured out. Yet, when i run the python, it gives me this error:
image
I am not understanding how the lines aren’t indexable?
Here are my inputs:

And finally here is the python: I appreciate any insight you could provide.

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

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

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

doc = DocumentManager.Instance.CurrentDBDocument

host_id_value = IN[0]
lines = UnwrapElement(IN[1])
force = IN[2]
moment = IN[3]
LLType = UnwrapElement(IN[4])

loads = []

TransactionManager.Instance.EnsureInTransaction(doc)
for line in lines:

    for host_id_value,lines,force,moment,LLType in zip(host_id_value,lines,force,moment,LLType):
       new_load = LineLoad.Create(doc,ElementId(host_id_value),line[1].ToXyz(),force.ToXyz(),moment.ToXyz(),LLType)
       loads.append(new_load)
   
TransactionManager.Instance.TransactionTaskDone()
OUT = loads

First up, pluralize your variables correctly and things will make more sense; i.e. use forces when you have many of them, forceLists when you have lists or forces, and force when you have only own force.

Nothing works on my end as I don’t have any files, just snapshots of contextless code.

Comment what you think each line of code is doing here by putting a # at the end of the line and then writing down what it does.

Something like this:
#for each line
#zip the hostIds, lines, forces, moments and llTypes into groups containing a hostId, line, force, moment, and llType.
#Generate a line load as newLoad
#append newLoad to the loads list

Now you likely noticed that you used ‘line’ in two comments, which is part (all?) of the issue here. My guess is you have no need for the first for loop.

1 Like

Unfortunately i cannot send a file. All the components used to create these elements, lines, etc… are not just out of the box Autodesk elements. I also have excel inputs which are protected files. So i will do my best again to explain this: Prior to 2025 REVIT i had a script which i used to create custom line loads. This worked up until 2025.
Previous code shown here:
image
What i now need to develop using the new line load create method for 2025: The LineLoad.Create method wanted is shown here:
LineLoad.Create(Document document, ElementId hostElemId, Curve curve, XYZ forceVector1, XYZ momentVector1, LineLoadType symbol) - Creates a new custom line load within the project.
The input values i have are as shown:


The error i am now receiving after trying option gazillion i get: I have tried different methods for defining the curve as well and am not getting the result.

And finally the code:

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

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

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

doc = DocumentManager.Instance.CurrentDBDocument

#Input values added here

host_id_value = IN[0]
lines = UnwrapElement(IN[1])
forces = IN[2]
moments = IN[3]
LLType = UnwrapElement(IN[4])

loads = []

#Zip Host IDs,Lines,Forces,Moments and Line Load Type LLType

TransactionManager.Instance.EnsureInTransaction(doc)
for host_id_value,lines,forces,moments,LLType in zip(host_id_value,lines,forces,moments,LLType):
    new_load = LineLoad.Create(doc,ElementId(host_id_value),curve(lines),forces.ToXyz(),moments.ToXyz(),LLType)#Generate line loads
    loads.append(new_load)#Append new load to list
   
TransactionManager.Instance.TransactionTaskDone()
OUT = loads

If you wrote this before, why are you struggling so much now? Just trying to wrap my head around if this is ‘the IronPython2’ engine was easier to author in or of there is another issue at play.

As far as your files…
Post a non-project file and a simplified dyn. No one needs or wants the excel or any real project content nor was it asked for. Start a new rvt with one beam in it and thr. Start a new dyn and add the Python node to it. From there develop the minimal inputs using atring and number nodes in order to add two loads o to the beam. Then post the dyn and the source RVT on which you configured it. From there functional Python can be written which you can use in the context of the larger automation.

Short of that… this is like a voluntary root canal for you and those of us trying to help.

This warning is telling you that you’re calling curve on line 28, but that doesn’t exist. By the looks of it (can’t confirm as you haven’t provided anything to confirm with) the problem is the curve(lines) bit. However I am clueless as to what you’re trying to do there. Can you explain?

It has nothing to do with the python method. Same error in all python engines. I guess what I am trying to explain is that creating the error in a basic form will not be what’s occurring. Currently there are detail components which run through another script and total up line loads for each structural wall in a project. These components then get an XY coordinate for the point and line load locations.
These loads then get broken down into their appropriate load cases and values. This ends in the result nodes which get inputted into the python in question.
These then get created on the overall slab (analytical panel). So as for recreating I will give it a go if that’s absolutely necessary to answering the initial issue?
The issue is the defining the curve portion of the python. The input node provides the needed lines but I am trying to get that to play nicely in the python and produce a result. That’s where the error occurs.
The new 2025 line load create requires a curve input for the location of the load in lieu of allowing start and end points for the load. I apologize for my lack of not explaining this well or not clear.

So what I am attempting to do is take the node with lines and input into the python so that the LineLoad.Create accepts that value input. That’s my only failure getting the load to create.

Ok, so the code I sampled above is attempting to create a curve from a line? Is that line from Dynamo geometry or something else? Instead of calling that method in the load creation, put it on the line before as a new variable.

Something like myCurve = curveCreationMethodHere and then call myCurve in the load creation area.

My question on the ‘how did you build the previous version’ was questioning if you managed this easier in the older version of Dynamo (indicating the team could do better now). Or was this code written by someone else?

That portion of code is attempting to create the curve part as that is what the new LineLoad.Create requires. In previous versions of the LineLoad.Create you were able to input the start and end points of the line which worked much easier. The geometry is coming from locations of detail component line extents. Which gives me a simple line, which then from what I am understanding, needs to be converted to a curve within the python.

Yes previous version I developed originally and had no issue. Once Revit is now requiring an analytical surface, panel, etc for a load to be hosted on, it has become more difficult. Previously all you needed was the coordinates and what type of load you want to place.

I would start by refactoring your inputs - dropping five lists of 435 items and then zipping is always going to be a bit messy.
Firstly look at your inputs - lost of repeated host ids, so lets group data by host id. To do that we create a list of lists, transpose and group by key and finally turning into a dictionary


If the LineLoadType is constant just use the same object, or if it is the default just use None
If you are extracting curves from the host you can use the constructor using the index of the curves on the analytical surface [link]
Here is example (pseudo) code

def unwrap_payload(load):
    """load [Curve, Force, Moment, LineLoadType]"""
    curve, force, moment, lineloadtype = load
    return UnwrapElement(curve), force.ToXyz(), moment.ToXyz(), UnwrapElement(lineloadtype)

# The inputs to this node will be stored as a list in the IN variables.
data = IN[0]

# Place your code below this line

# Start Transaction
output = {}

for host, loads in data.items():
    host_id = ElementId(int(host))
    for load in loads:
        lineload = LineLoad.Create(doc, host_id, *unwrap_payload(load))
        output.setdefault(host, []).append(lineload)

# Close Transaction

# Assign your output to the OUT variable.
OUT = output
1 Like

So the geometry is a Dynamo geometry object? Look into the conversion methods (ToRevitType) as an example. Bit late here or I’d build an example for you, but searching the forum will give many good examples.

I will give your idea a go. I agree on the silliness for the OfRepeated items, but oddly the line loads will not create unless you have a 1 to 1 for each input into the Python. Its very odd, but that was the only way i could find for it work. So 435 lines, means 435 of the same host ID and 435 of the load type.

I thank you for all your help. I will continue my search and appreciate your patience. I struggle when something so simple turns into a situation such as this. Original script took me about 10 minutes which included testing. This current escapade i have been going on almost 2 days.

Unfortunately this doesn’t work, as typically the Host ID will be the same for all. The line loads are to be placed on an analytical panel (floor), so unless i am not seeing something, the groupby won’t act correctly?

Should work, but even if not the issue isn’t in the Python method anymore, but your larger context which we don’t have as we don’t have a dataset. I’m tied up writing code for the day job today so won’t be able to troubleshoot much, but if you get a small sample posted before I take lunch (~3 hours from now) I can have a look then.

@Mike.Buttery I finally got a chance to get this into graph. Getting an error from the python showing this: I did not edit or add anything to what you have provided.
image

I see your #placecodebelow this line statement but am unsure which part of code. Being all the inputs are already present is there something else you are recommending i input?

When i do add the beginning defintions i get an error which is the same as i was getting with my original python.

My code was indicative, you have to do some debugging…
‘ElementId’ is not defined - have you imported it?

Convert the lines as part of the unwrap (apologies, generally geometry has it’s own converters. See here)

def unwrap_payload(load):
    """load [Curve, Force, Moment, LineLoadType]"""
    curve, force, moment, lineloadtype = load
    return curve.ToRevitType(), force.ToXyz(), moment.ToXyz(), UnwrapElement(lineloadtype)

Element ID issue has been fixed. I just updated the imports. I just adjusted code per your recommendation and am now getting errors that i am hoping you understand because i have never seen anything like it.
Error shows:
image
image
image
image