I´m using this working python code to set the visibility of grid bubbles in a single view.
g = UnwrapElement(IN[0])
bx = UnwrapElement(IN[1])
by = UnwrapElement(IN[2])
v = UnwrapElement(IN[3])
TransactionManager.Instance.EnsureInTransaction(doc)
for g, bx, by in zip(g, bx, by):
if bx and by:
g.ShowBubbleInView(DatumEnds.End1,v)
g.HideBubbleInView(DatumEnds.End0,v)
elif bx:
g.HideBubbleInView(DatumEnds.End1,v)
g.ShowBubbleInView(DatumEnds.End0,v)
elif by:
g.ShowBubbleInView(DatumEnds.End1,v)
g.HideBubbleInView(DatumEnds.End0,v)
else:
g.HideBubbleInView(DatumEnds.End0,v)
g.ShowBubbleInView(DatumEnds.End1,v)
TransactionManager.Instance.TransactionTaskDone()
doc.Regenerate()
OUT = g
Now i want to make it work for a list of views, this is my failing attempt. Notice that for every view there is a list of grids and a list of bools.
g = UnwrapElement(IN[0])
bx = UnwrapElement(IN[1])
by = UnwrapElement(IN[2])
v = UnwrapElement(IN[3])
views = v
TransactionManager.Instance.EnsureInTransaction(doc)
for views in v:
for g, bx, by in zip(g, bx, by):
if bx and by:
g.ShowBubbleInView(DatumEnds.End1,v)
g.HideBubbleInView(DatumEnds.End0,v)
elif bx:
g.HideBubbleInView(DatumEnds.End1,v)
g.ShowBubbleInView(DatumEnds.End0,v)
elif by:
g.ShowBubbleInView(DatumEnds.End1,v)
g.HideBubbleInView(DatumEnds.End0,v)
else:
g.HideBubbleInView(DatumEnds.End0,v)
g.ShowBubbleInView(DatumEnds.End1,v)
TransactionManager.Instance.TransactionTaskDone()
doc.Regenerate()
OUT = g
The warning gives a clue ‘List object’ has no attribute… Instead of ‘Grid object’ for example… I also try to comment my way through the code, explaining it to myself helps me better understand what is going on. Also trying to keep everything very obvious helps me
viewList = UnwrapElement(IN[3]) #unwrap everything in the list
TransactionManager.Instance.EnsureInTransaction(doc) #start transaction
for view in viewList: #get each view in the viewList
for g, bx, by in zip(g, bx, by): #run through everything in the sub lists, keep them the same length
if bx and by: #boolean check
g.ShowBubbleInView(DatumEnds.End1,view) #in each view show if the end value is true
TransactionManager.Instance.EnsureInTransaction(doc)
for ELEMENT in LIST:
(do something with ELEMENT)
TransactionManager.Instance.TransactionTaskDone()
But I´m still getting the error.
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import *
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
g = UnwrapElement(IN[0])
bx = UnwrapElement(IN[1])
by = UnwrapElement(IN[2])
viewList = UnwrapElement(IN[3]) #unwrap everything in the list
TransactionManager.Instance.EnsureInTransaction(doc)
for view in viewList: #get each view in the viewList
for g, bx, by in zip(g, bx, by): #run through everything in the sub lists, keep them the same length
if bx and by: #boolean check
g.ShowBubbleInView(DatumEnds.End1,view) #in each view show if the end value is true
g.HideBubbleInView(DatumEnds.End0,view)
elif bx:
g.HideBubbleInView(DatumEnds.End1,view)
g.ShowBubbleInView(DatumEnds.End0,view)
elif by:
g.ShowBubbleInView(DatumEnds.End1,view)
g.HideBubbleInView(DatumEnds.End0,view)
else:
g.HideBubbleInView(DatumEnds.End0,view)
g.ShowBubbleInView(DatumEnds.End1,view)
TransactionManager.Instance.TransactionTaskDone()
doc.Regenerate()
OUT = g
You’re still not looping properly. This is the same ideas as for ELEMENT in LIST: but you’re essentially writing for LIST in LIST:. You’re reducing the list variable to the same list variable when you need to define a new variable for the items within each list.
Nick is right… All this is so abstract, so I like to try and help myself…
gridList = UnwrapElement(IN[0])
headList = UnwrapElement(IN[1])
tailList = UnwrapElement(IN[2])
viewList = UnwrapElement(IN[3]) #unwrap everything in the list
for grid, head, tail in zip(gridList, headList, tailList): #run through everything in the sub lists, keep them the same length
if head and tail: #boolean check
grid.ShowBubbleInView(DatumEnds.End1,view) #in each view make the end show if the value is true
Ok, i have to loop views in list because i don´t have a single view anymore, i have a list of views.
Because i have a list of views, the grid list and bool list now turn into a L3 list with sublists. This is why i have to loop again to get items x,y,z in xList, yList, zList. Right?
Code gets looking better and better, using proper names really helps! But still the same error.
gridList = UnwrapElement(IN[0])
headList = UnwrapElement(IN[1])
tailList = UnwrapElement(IN[2])
viewList = UnwrapElement(IN[3]) #unwrap everything in the list
TransactionManager.Instance.EnsureInTransaction(doc)
for view in viewList: #get each view in the viewList
for grid, head, tail in zip(gridList, headList, tailList): #run through everything in the sub lists, keep them the same length
if head and tail: #boolean check
grid.ShowBubbleInView(DatumEnds.End1,view) #in each view show if the end value is true
grid.HideBubbleInView(DatumEnds.End0,view)
elif head:
grid.HideBubbleInView(DatumEnds.End1,view)
grid.ShowBubbleInView(DatumEnds.End0,view)
elif tail:
grid.ShowBubbleInView(DatumEnds.End1,view)
grid.HideBubbleInView(DatumEnds.End0,view)
else:
grid.HideBubbleInView(DatumEnds.End0,view)
grid.ShowBubbleInView(DatumEnds.End1,view)
TransactionManager.Instance.TransactionTaskDone()
You only need an extra dimension to your grid lists if the grid list changes with each view. If the grids are the same for each view then you would still have just one list of grids and one list of views. They way that your code is written write now you loop through each view individually, and with each view you also loop through each grid in your list of grids. If you have separate grids for each view then you would need to zip them all together because each sublist corresponds with its paired sublists from the other lists.
For every view there is a sublist of grids and a sublist of bools. Different for every view.
These grids and bools have the same list structure. I´m zip´ing these grids and bools together.
So far so good.
Now each view loops through the full zip list of grids and bools and this is causing the error.
What i want is to loop each view with the right sublist. The Sublist with the same index as the view.
Right. So zipping lists together essentially means that your code will loop through them together. This is necessary when you have multiple items or sublists that have to be utilized specifically with their counterpart in a different list. You still have to loop through the items in a sublist when looping through zipped lists though. So your code would look something like this:
gridList = UnwrapElement(IN[0])
headList = UnwrapElement(IN[1])
tailList = UnwrapElement(IN[2])
viewList = UnwrapElement(IN[3])
for grids, heads, tails, view in zip(gridList, headList, tailList, viewList):
for grid, head, tail in zip(grids, heads, tails):
The first loop goes through each subitem. For grids and booleans this is a sublist matched up with the view in the viewList. But from there you still need to go one more level to get the actual grid and boolean values so you loop one more time.
It really is amazing what i can achieve with visual programming and how lost I am at python
So Sublists always require looping twice, check.
Now there is no error, but it´s also nothing happening, bubbles don´t change.
So in section views nothing happens if i select one view and nothing happens if i select more views.
BUT if i select a planview it works, if i select multiple ones it only works for one planview.
You need to make the main code work for lists since you could potentially have a list of views. To make it work with a single view you then just convert the single view to a list of 1 view.
You need to maintain the same list levels regardless of whether you have multiple views or one view. This is for all your lists/sublists. One view means one list of grids, but you need to convert that (as well as the booleans) to a list with sublists.
Unfortunately you can’t just convert the single item to a list like that because you would also be adding another list level to your multiple views. You need to use a conditional statement to only add a list level when dealing with a single view.
Many python scripts will check to see if an input is already a list or not and convert accordingly.
if isinstance(IN[0], list):
views = UnwrapElement(IN[0])
else:
views = [UnwrapElement(IN[0])]
You could also use a codeblock if you’re confident your views will always be a single item or flattened list.
I understand, but don´t know how to (in python) handle the Grids and Bools that are already lists .
For them I would have to check if input=list@level2 and if thats true to make a list@level3 out of it.
You would assume that the view structure determines the grid and boolean structures as well. If the view input is a single item then it gets wrapped in a list and the grids and booleans also get wrapped in an extra list layer.