Node Output is "null" but passes values

Hello all,
Ok, I actually have two questions, but they are related and any help would be appreciated.

Question 1:
I have a python node that seems pretty simple, and I do generally get what I am after, but the output of the node shows null, but has a number of items with it.

Here is an image of it after hovering on the node. You can see that it show there are 307 items in the output.

But when I try to expand the list out, I just get a null.

You can also see that the watch node doesn’t produce any results. Anyone have any idea why this would happen? I also tried putting this in a custom node and that provided the same results.

Question 2:

The Custom node is trying to collect all Family Types of a specific category within a Document that is loaded in the background. When I run this script the first time, everything tends to go ok except the first document doesn’t close. Because of this I have to restart everything each time to get it to reset because the document hangs from then on.

Is there something in my node or the way I am handling the Closing of the document that is causing this?

Full Error:
“Close is not allowed when there is any open sub-transaction, transaction or transaction group.”

import System
import clr
clr.AddReference("RevitNodes")
import Revit
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument
dataEnteringNode = IN

cats = IN[0]
docs = IN[1]

elems = []
try:
    for fd in docs:
	TransactionManager.Instance.EnsureInTransaction(fd)
	families = set()
	for cat in cats:
		collector = FilteredElementCollector(fd)
		collector.OfCategory(System.Enum.ToObject(BuiltInCategory, cat.Id))
		collector.OfClass(FamilySymbol)
		types = collector.ToElements()
	elems.append(types)
		#for type in types:
		#	families.add(type)
		#families = list(families)
	TransactionManager.Instance.TransactionTaskDone()
except:
    pass

OUT = elems, docs

Thanks in advance for any help you can offer!

You’re trying to return references to elements that were contained inside of documents that you just closed. Thus when the graph tries to display a representation of those elements, it fails and things go horribly wrong… :slight_smile:

3 Likes

@Dimitar_Venkov I assume that since the document was being closed down stream that the element / information should still show up. I assume that I should send the Element.Name or something to another list if I want to track which ones on come through.

To my second question, would you see why it would say there is hanging transaction? Should I force close each one rather than TaskDone? I have done this in other graphs, but it take A LOT longer for it to run. A suggestion I had seen was to use TaskDone to make it more efficient. I guess Slow is better than Failing, but any thoughts would be appreciated?

Do you think it would be best to try and wrap the whole process into a node? I have thought about that and just feed it paths and Categories and let it open, work, and close all contained?

To follow on from @Dimitar_Venkov’s comment, when you close the Document you’re closing it inside of memory, thus the downstream/upstream data flow will fail when the trying to re-read that content.

As an example, you can also Dispose() of Geometry downstream using Python that will then also unload it from memory - causing nulls upstream. You can check the following issue on the Github registrar: https://github.com/DynamoDS/Dynamo/issues/9073

2 Likes

Thanks @solamour for the additional feedback. After thinking more about this, it seemed better to wrap all of this up into one node. One key piece was calling the Transaction manually rather than the TransactionManager. No matter how I tried to slice it, it kept telling me I couldn’t edit because no transaction was open.

import System
import clr
clr.AddReference("RevitNodes")
import Revit
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference("RevitAPI")
import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)

uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

paths = IN[0]
if not isinstance(paths, list): paths = [paths]
cats = IN[1]
if not isinstance(cats, list): cats = [cats]

status = []
errorReport = None
for path in paths:
	try:
		doc = app.OpenDocumentFile(path)
		trans = Transaction(doc,'del')
		for cat in cats:
			collector = FilteredElementCollector(doc)
			collector.OfCategory(System.Enum.ToObject(BuiltInCategory, cat.Id))
			collector.OfClass(FamilySymbol)
			types = collector.ToElements()
		trans.Start()
		for type in types:	
			doc.Delete(type.Id)
		trans.Commit()
		doc.Close(True)
		status.append('Closed')
	except:
		import traceback
		errorReport = traceback.format_exc()

if errorReport is None:
    OUT = status
else:
    OUT = errorReport

Thanks for the help on this one, I needed to learn more about how Dynamo handles items up and down stream of closures and deleted items.

2 Likes

Hey Sean,

Did you get the answer to your first question? I’m also facing the same problem. The node shows the number of items (1249) but doesn’t enlist the result and says “Null”.

Your kind help would be appreciated.

Thanks.

Hey @rahim.rajpari ,

So I think… If your graph opens a file, grabs data, then closes the file… The graph can’t show you the info it was grabbing, because the file is now closed.

Normally that wouldn’t happen because Dynamo usually works with an open Revit file.

If you want that data you’ll need to ‘use it’ before closing the file. Though I believe there might be a Remember node somewhere?

Hopefully that’s about right :slight_smile:

Mark

I believe the answer is that you can’t see the data in this way as mentioned above. You would need to store it, or pull the data out in some other way to be able to view the actual elements. I have ran into the same problem using “Delete” nodes as well. @Mark.Ackerley may be on to something with the Remember node, which I think was developed for Refinery, but may just serve this purpose, but not entirely sure how it will handle other documents.

2 Likes

Hi SeanP, when you say you need to “store” the data what exactly do you mean? I’ve ran into this problem of nodes returning nulls but still passing data and I’m trying to find a work around as it’s making development a nightmare. thanks

Something like getting the ElementId as a number before its deleted or pulling the name of the Family or Type or whatever your working with to just a string list prior to doing whatever the “null” node is doing. Just some way of getting back to the info or referencing it.