Trying to modify a python script and have the result be nested lists, not just multiple compiled lists of all the values. Here’s the bottom of the code :
Mod Edit: formatted code - @danny.jones8FB78, please make sure this is correct
for wall in walls:
line = wall.Location.Curve
lineDir = line.GetEndPoint(1) - line.GetEndPoint(0)
doc=wall.Document
geoElement = wall.get_Geometry(options)
for obj in geoElement:
if isinstance(obj,Solid):
for f in obj.Faces:
faceNormal = f.FaceNormal
if isParallel(faceNormal,lineDir):
refArray.Append(f.Reference)
for id in wall.CurtainGrid.GetVGridLineIds():
gridLine = doc.GetElement(id)
gridGeo = gridLine.get_Geometry(options)
for obj in gridGeo:
if isinstance(obj,Line):
refArray.Append(obj.Reference)
OUT = [refArray for wall in walls]
If your walls are straight the LocationCurve (line) will have a Direction property
For walls joined at angles the face normal may not be parallel to the direction - perhaps look at HostObjectUtils class to exclude top, bottom and side faces
[refArray for wall in walls] just repeats refArray for the number of walls
Collect you info in a list per iteration and then append to your output list
Something like this?
for wall in walls:
collector = []
line = wall.Location.Curve
lineDir = line.Direction
doc=wall.Document
geoElement = wall.get_Geometry(options)
for obj in geoElement:
if isinstance(obj,Solid):
for f in obj.Faces:
faceNormal = f.FaceNormal
if isParallel(faceNormal, lineDir):
collector.Append(f.Reference)
for id in wall.CurtainGrid.GetVGridLineIds():
gridLine = doc.GetElement(id)
gridGeo = gridLine.get_Geometry(options)
for obj in gridGeo:
if isinstance(obj,Line):
collector.Append(obj.Reference)
refArray.append(collector)
OUT = refArray
I appreciate the help. In theory I’m understanding the logic. Dynamo is now throwing an error at the “collector.Append(f.Reference)” line. File “”, line 30, in
AttributeError: ‘list’ object has no attribute ‘Append’
Pasting in the whole code… still not working. “‘ReferenceArray’ object has no attribute ‘Add’”
import clr
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
walls = UnwrapElement(IN[0])
if not hasattr(walls, '__iter__'):
walls = [walls]
def isParallel(v1,v2):
return v1.CrossProduct(v2).IsAlmostEqualTo(XYZ(0,0,0))
refArray = ReferenceArray()
options = Options()
options.ComputeReferences = True
options.IncludeNonVisibleObjects = True
for wall in walls:
collector = []
line = wall.Location.Curve
lineDir = line.Direction
doc=wall.Document
geoElement = wall.get_Geometry(options)
for obj in geoElement:
if isinstance(obj,Solid):
for f in obj.Faces:
faceNormal = f.FaceNormal
if isParallel(faceNormal, lineDir):
collector.Add(f.Reference)
for id in wall.CurtainGrid.GetVGridLineIds():
gridLine = doc.GetElement(id)
gridGeo = gridLine.get_Geometry(options)
for obj in gridGeo:
if isinstance(obj,Line):
collector.Add(obj.Reference)
refArray.Add(collector)
OUT = refArray
There is the ‘collector’ which is a list (lowercase append) and the ‘refArray’ which is a Revit ReferenceArray.
The former needs the lowercase append.
The later needs the uppercase Append.
My guess is that when the capitalization is resolve you’re going run into an issue with trying to append an untyped list (‘collector’ in your code) to a ReferenceArray, with a warning that goes something like “could not find an method Append of the class ReferenceArray which takes arguments of type List”
You want to put the references in the reference array.
Sorry about the (A/a)ppend - that was VS Code autocomplete having a senior moment
Since you’re after a ReferenceArray collection swap the list collector and array as the array takes a Reference as an input. I’ve done a slight refactor and changed variable names to python convention
import clr
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
def isParallel(v1, v2):
return v1.CrossProduct(v2).IsAlmostEqualTo(XYZ(0, 0, 0))
doc = DocumentManager.Instance.CurrentDBDocument
walls = UnwrapElement(IN[0])
if not hasattr(walls, "__iter__"):
walls = [walls]
options = Options()
options.ComputeReferences = True
options.IncludeNonVisibleObjects = True
ref_array_list = []
for wall in walls:
ref_array = ReferenceArray()
line_dir = wall.Location.Curve.Direction
# doc = wall.Document # Uncomment if walls are in linked doc
geo_element = wall.get_Geometry(options)
for obj in geo_element:
if isinstance(obj, Solid):
for f in obj.Faces:
if isParallel(f.FaceNormal, line_dir):
ref_array.Append(f.Reference)
for id in wall.CurtainGrid.GetVGridLineIds():
grid_line = doc.GetElement(id)
grid_geo = grid_line.get_Geometry(options)
for obj in grid_geo:
if isinstance(obj, Line):
ref_array.Append(obj.Reference)
ref_array_list.append(ref_array)
OUT = ref_array_list