Line Loads Via Python

I have followed a previous topic to develop a script using python to create line loads within REVIT. I am struggling with what best way is to get the python script to loop when I input a list. I have a list of XY start/end point coordinates, a line load type, the loads needed and what level i want them to be created on. Currently the script only works when i input only one value for each item. Is it possible to create a loop within the Python to develop several lineloads at several coordinates? Below is the original script. I

Hi,

you can use zip() function to iterate over several iterables in parallel

example

for line, host, curveIndex, forceVector1, momentVector1, symbol in zip(lst_line, lst_host, lst_curveIndex, lst_forceVector1, lst_momentVector1, lst_symbol):
	new_load = LineLoad.Create(doc, host, curveIndex, forceVector1, momentVector1, symbol)

Thank you for the link. Looking at your example, can you help me understand? When you say symbol, what is that referencing? My input elements as shown in image and copied below would be:

lines = UnwrapElement(IN[0])
force = UnwrapElement(IN[1])
axial, moment = IN[2].ToXyz(), IN[3].ToXyz()
level = UnwrapElement(IN[4])
loads =

and then go into the following to actually create and show a load within REVIT:

TransactionManager.Instance.EnsureInTransaction(doc)
sp = SketchPlane.Create(doc, level.Id)
for l in lines:
new_load = LineLoad.Create(doc, l[0].ToXyz(), l[1].ToXyz(), axial, moment, force, sp)
loads.append(new_load.ToDSType(False))
TransactionManager.Instance.TransactionTaskDone()
OUT = loads

So i am assuming the zip() gets added prior to each item within the LineLoad,Create ( )? Sorry for asking what may be a silly question. I attempted to use the zip prior but i put the zip prior to the UnwrapElement items and could not get it to work properly.

It’s just the name of the argument/variable. In your case you called it force. In the Revit API, “symbol” is the same as “type”. So when the argument is for a Line Load Type that’s the same as the Line Load Symbol.

The zip() function essentially merges items from multiple lists by index, allowing you to step through multiple lists at once.

Example: If you wanted to add three numbers a + b + c but across a list of values you could use zip() to add each set of values one at a time.
image

2 Likes

I was under the impression that the “host” shown in the example was the Line Load type. Being i am not using a host element in REVIT and instead using a list of XY coordinates to get a start and end point for length of Line Load. So with that said, does the “host” item in the example just gets removed?

I also have attached the portion of my Dynamo script if it helps you any.
Originally i had a RepeatedItems node to ensure all my lists were the same length. But not sure if that was necessary?

You have to provide the necessary arguments (inputs).

You’ll have to choose which creation option is best for your use case.

Pre 2023

2023

I have all the inputs. Inputs work if I just use 1 item from each list. But when trying to loop the entire list, I get errors relating to xyz attributes. Almost as if you can’t input more than one load at a time. Which seems like that can’t be correct, and that’s why I came here to see if there was option to loop in the python portion.

Can you show us your code using the loop and any errors you get from it? Make sure you use preformatted text (</>) so it formats correctly.

**

**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

startPs = IN[0].ToXyz()
endPs = IN[1].ToXyz()
force = IN[2].ToXyz()
moment = IN[3].ToXyz()
LLType = UnwrapElement(IN[4])
level = UnwrapElement(IN[5])

loads =

TransactionManager.Instance.EnsureInTransaction(doc)
sp = SketchPlane.Create(doc, level.Id)
for loads in zip([startPs],[endPs],[force],[moment],[LLType]):
new_load = LineLoad.Create(doc,startPs,endPs,force,moment,LLType,sp)

TransactionManager.Instance.TransactionTaskDone()
OUT = loads

error i get is as follows:
Warning: AttributeError : ‘list’ object has no attribute ‘ToXyz’ [’ File “”, line 18, in \n’]

Inputs to Python Node as Shown.

If i remove the zip from python and use a FirstItem node from each input, the python works and a load is created in REVIT. Somehow the python or REVIT is only allowing 1 set of XY start/end points, one force, one moment and one lineload type. I even attempted to use RepeatedItems node for the moment and lineload type so that all lists would be the same length. This method did not work either. I appreciate you guys help being i am beating my head against the wall.

Just as a reminder again, make sure you use preformatted text with any code snips. Otherwise the code won’t format properly and it becomes very hard to read.
image

Make sure you’re only zipping the inputs that are lists and that each list has the same length. That being said, the current issue according to the error has nothing to do with zipping. You can’t convert an entire list to XYZs. You have to convert the individual item within the loop.

Sorry I did the <> part manually with text prefix. From what I’ve seen multiple XYs will work if I index them using only one axial force. So if I did a unique items and then indexed all the associated XYs per load I could get multiple Xy loads to show in revit. Issue with that is that I would have the same python script for each load magnitude to actually develop load in revit which could mean 30 or more of the same python nodes for each magnitude which becomes cumbersome. That’s where my struggle is. Is it possible to elaborate or point me in right direction as to what you are thinking in regards to the loop? For some reason I feel as though there is limitations when inputting multiple load values at different XYs at same time.

There’s a chance you’re right and it’s just not possible, but I’d be pretty surprised.

What I’d suggest doing now is duplicating the last three inputs to match the rest of the list lengths. Then you don’t have to worry about which items are being looped and which aren’t. You just loop through all of them together.

Even when using a repeatediem node to match list lengths the python does not work. I have tried a couple different zip combinations and at the end i get the same error regarding the xyz attributes. I have tried several combinations and locations of the zip function. If you have any recommendations to the following code, please let me know. Keep in mind, that the copied code was my most recent dart at the wall to see if it would work. I am beyond lost at the moment why no matter what i put in their it doesn’t work.

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

startPs = IN[0].ToXyz()
endPs = IN[1].ToXyz()
force = IN[2].ToXyz()
moment = IN[3].ToXyz()
LLType = UnwrapElement(IN[4])
level = UnwrapElement(IN[5])

loads = []

TransactionManager.Instance.EnsureInTransaction(doc)
sp = SketchPlane.Create(doc, level.Id)
for start,end,force,moment,LLType,level in zip(startPs,endPs,force,moment,LLType):
    new_load = LineLoad.Create(doc,startPs,endPs,force,moment,LLType,sp)
   
TransactionManager.Instance.TransactionTaskDone()
OUT = loads

Here is the original code i had without zip function that works when entering only one item from each list isolated.

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

dataEnteringNode = IN
startPs = IN[0].ToXyz()
endPs = IN[1].ToXyz()
force = IN[2].ToXyz()
moment = IN[3].ToXyz()
LLType = UnwrapElement(IN[4])
level = UnwrapElement(IN[5])

loads = []

TransactionManager.Instance.EnsureInTransaction(doc)
sp = SketchPlane.Create(doc, level.Id)
new_load = LineLoad.Create(doc,startPs,endPs,force,moment,LLType,sp)  
TransactionManager.Instance.TransactionTaskDone()

OUT = loads

As I mentioned before, this is the issue you’re currently facing. Your code isn’t even getting to the zip() line. The ToXyz() conversion only works on a single point. You can’t convert a whole list at once like that. You need to do the conversion on the individual item, which would be in the new_load line. You’re also not mapping the zip() variables correctly. In the example for a,b,c in zip(a_list,b_list,c_list) the a,b,c variables are the individual items from looping through a_list,b_list,c_list. They are the variables you use in the LineLoad.Create arguments. Right now you’re using the same variable in both places which is doing nothing.

It should look something like:

for start,end,force,moment,LLType,level in zip(startPs,endPs,forcePs,moments,LLTypes):
    new_load = LineLoad.Create(doc,start.ToXyz(),end.ToXyz(),force.ToXyz(),moment.ToXyz(),LLType,sp)

I have already made the attempt using this specific code. I have tried probably 30 different variations and get the same issue regarding the XY regardless if i put the .ToXyz in the lineload create or up at the input portion. I appreciate all the help and will try to dig deeper into this to see what can be done to make it work. Seems as though there is a limitation somewhere, being the code works completely fine when putting in only 1 load magnitude.

It doesn’t matter how many variations you try if you’re not using the methods properly. So far you haven’t shown us any code that’s being used correctly so it’s hard to say what the actual problem is. A line of code that works for a single item doesn’t mean it will work for a list of items.