Error with custom node despite dynamo script working

Hi all!

I’ve been stuck all day trying to find solutions for an issue that I have.

I have a script that ends with a filtering node that filters a nested list that has two levels such that I get two IN and two OUT, as can be seen in img bellow. With the custom node it returns a mess while showing an error of “convert a non convertable…”, and it isn’t quite clear what the issue is, while the regular script outputs a clean list of two list from the IN.
Earlier on I had the issue of converting a non convertable and found the solution on the forum to filter by type and that treated the problem (I was trying to filter the elements of type Level by name so I ended up filtering out the types that were string).
So basically now I am still stuck with this error of the output of the custom node.

Check your inputs. They need to have the right data type and structure.

These are the inputs for the custom node, taking in lists of levels and lists of walls.

These are the actual inputs into the custom node. Is something incorrect?

You have indicated levels as a list of lists of levels.

You are providing a list of levels.

This seems likely to be problematic, as the subsequent Python node would need to written process the list by taking a list of levels and then pulling each level.

However you are providing a list of levels instead and therefore the Python start to iterate over the list and wouldn’t find another list so… failure would be imminent.

On the matter as input as list or list of list, I managed to set up the node that it will work with both types using a recursive unwrapping, but I am still receiving the same result: the issue of nonconvertable error and mainly having the output from the filter dictionary being a mess, as seen in attached image.

I am attaching the dyn file with the script consisting of the custom node in case it helps.
GetWalls_MessyOutput_DynamoForum.dyn (56.4 KB)

mess of an output:

output of dynamo script and what I would expect (same script as in custom node):

GetName node successfully returns output with different level lists inputs:

Try using a single depth list as the input type for each - the structure of the inputs will mean you’re only testing wall N against level N instead of against the full set of inputs.

Hi,

a solution with Python

import clr
import sys
import System
#
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS

#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB

#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

toList = lambda x : x if hasattr(x, "__iter__") and not isinstance(x, (str, System.String)) else [x]

lst_level = toList(UnwrapElement(IN[0]))
out_data = []

for level in lst_level:
    level_id = level.Id
    
    ruleA = ParameterFilterRuleFactory.CreateEqualsRule(ElementId(BuiltInParameter.WALL_BASE_CONSTRAINT), level_id)
    filterA = ElementParameterFilter(ruleA)
    walls_base_constraint = FilteredElementCollector(doc).OfClass(Wall).WherePasses(filterA).WhereElementIsNotElementType().ToElements()
    
    ruleB = ParameterFilterRuleFactory.CreateEqualsRule(ElementId(BuiltInParameter.WALL_HEIGHT_TYPE), level_id)
    filterB = ElementParameterFilter(ruleB)
    walls_top_constraint = FilteredElementCollector(doc).OfClass(Wall).WherePasses(filterB).WhereElementIsNotElementType().ToElements()
    out_data.append([f"{level.Name}_walls_base_constraint", walls_base_constraint])
    out_data.append([f"{level.Name}_walls_top_constraint", walls_top_constraint])

OUT = out_data
2 Likes