Custom UI Node Geometry Preview

I’ve been tinkering with developing Dynamo nodes over the last couple of years, and while I have been fine for the most part with Zero Touch and Python, there are some things that I’ve wanted to do that would require a little more interactivity. I’ve implemented a few things as Custom UI nodes that are working great, but I’m not getting any preview geometry to show up without connecting the output to another node that then provides the preview geometry.

On a relatively simple example, I’ve written one node (implementing NodeModel) to just extract mesh geometry from Revit elements similar to the Revit.Elements.Element.Solids node with an optional boolean to get only the mesh geometry in the current view, and functionally it’s working fine since I’m getting the meshes and have no problem working with them from that point on, but there’s no preview geometry coming out of it. I’m assuming I’m missing something, but so far I haven’t figured out what it is that tells the node to generate the geometry preview.

Have you tried to inherit the IGraphicItem interface and create a Geometry and Transform object?

There’s an example on the Dynamo GitHub for this (for the record, I haven’t tested this myself!):

So I’ve tried a few different variations on this and I still haven’t gotten very far. The IGraphicItem seems a little unnecessary in my case since the Tessellate method that it’s using seems like it could be done through the RequestVisualUdateAsync override from the NodeModel I’m already inheriting from. However, when I try to add the meshes to the IRenderPackage either in the Tesselate method of the IGraphicItem or the RequestVisualUpdateAsync method of the NodeModel, I still get no preview.

Doing more or less the same operations via Zero Touch work fine and display a preview mesh without having to inherit from IGraphicItem or anything else.

I have verified that the RequestVisualUpdateAsync method is being called, and the IRenderPackage does appear to be getting the meshes. The only thing I’ve done to verify the latter is that before and after calling the Tessellate method the IRenderPackage.MeshVertexCount does change and seems appropriate for what I’m sending it.

Here’s an example of extracting an Autodesk.Revit.DB.Mesh from Revit elements and converting it to an Autodesk.DesignScript.Geometry.Mesh:

There’s a ZeroTouch version in there, and a Custom UI version in there. Both versions work more or less the same, and just wind up outputting the meshes in slightly different list formats. The Zero Touch version will show a preview of the meshes on its own, the Custom UI version will not show the UI unless I plug it into something else. Even plugging it into a CodeBlock that just passes the data will give the mesh a preview. Another interesting thing I noticed is that plugging the output of the Custom UI version into a Watch3d also produces no preview within the Watch3d node. Maybe like there’s a wrapper for Revit elements there’s also a wrapper for DesignScript.Geometry elements?

The lack of preview isn’t a deal breaker by any means. The components I’ve been working on still generally work great and function as I expect, I just find it odd that there’s no geometry preview and unless I’m just being really dense here, no obvious way to get it to preview.

@Timothy_Logan1 what type does your node return into the graph? If that type doesn’t implement IGraphicItem then there will be no preview.

If you return a Dynamo geometry type it should have preview since I believe all our geo types implement IGraphicItem - many of the Revit.Elements do not.

A little clarification - it’s not your nodeModel that should implement IGraphicItem, it’s the type your nodeModel returns.

This one particular case is returning an Autodesk.DesignScript.Geometry.Mesh object. It takes a Revit element and translates the Autodesk.Revit.DB.Mesh, generated from tessellating the element’s solid geometry objects, into the Dynamo mesh. Doing this operation within a Zero Touch node, the output previews just fine. Doing it through a Custom UI type node it doesn’t show a preview. I have some other nodes I’ve made where no geometric preview is visible for elements from Autodesk.DesignScript.Geometry, but I can still manipulate the output geometry with no problems.

Take the following image as an example. I have two nodes that do mostly the exact same thing, one as Zero Touch (top) and one as a custom node inheriting from NodeModel. Both output the same data (slightly different list organization), but the Zero Touch will preview immediately, while the custom UI node will not. I can still do things to the output, like pulling the mesh vertices from the output mesh, but it won’t display (canvas background or Watch3d) unless I either manipulate the geometry or pass it through a Code Block that does nothing but pass along the data.

-Tim

@Timothy_Logan1 this looks like a bug. I wonder if the same behavior is present with other geometry types.

I took a quick look at your repo but it’s tough to reason about as you are overriding request visual async, you have implemented IGraphicItem on the node class… so theres a lot going on.

If possible I would try another creating another UI node, and simply return a new DynamoMesh when it runs, do you get preview then?

also, I do not think your getMeshes method needs to use mirrorData and engine access at all… you can just write a function that anticipates the inputNodes will be Revit.db.Meshes…

I think I have another node that outputs different geometry types, at least curves and points, so I can take a look at that in the morning when I’m back at work. The override for the RequestVisualUpdateAsync and the IGraphicItem are there just trying to get the preview to work, I didn’t have them initially.

The getmeshes method I think you’re referring to is only there because of the aforementioned RequestVisualUpdateAsync and IGraphicItem stuff. My use of it may just be my somewhat new experience in developing Dynamo nodes since I couldn’t think of any other way to get the output data from the node. The node could function identically if I stripped everything but the constructor and the BuildOutputAst override from the class. The rest of it is my non-working attempt to get the preview to show up.

The way the node this designed, it takes a list of Revit elements and tessellates the solid geometry objects within them using the RevitAPI’s tessellate method. The mesh that gets returned from that is then translated to a Dynamo mesh, which is what gets output by the node. There’s also an optional bool input that you can specify to only get the geometry in the current Revit view. I could try to make a node that just outputs some arbitrary mesh, maybe a cube, and see if it shows a preview.

I made a simple test with the previewing of meshes this morning by just creating a node that outputs a cube mesh that’s 10x10x10. While making this I noticed that my original Revit element to Dynamo mesh node was outputing an object, not a mesh. In reality it was a Mesh, but I took part of the code from another project I have where the output could be just about anything (different geometry, strings, integers, doubles, …).

So with this simple test, I made sure to set the output to a Dynamo mesh and then gave it a simple boolean toggle turn it on/off just to make sure it was responding correctly. It’s set up as a mesh and is super simple, but it still does not output a preview. Again, just passing it through a code block or something else will generate the preview.

I’ve pushed an update to the git repo where I’ve been testing it.

NodeModel
https://github.com/logant/DynamoPreviewTests/blob/master/CustomUITest/MeshFromElement_Simple.cs

Function
https://github.com/logant/DynamoPreviewTests/blob/master/CustomUIFunc/CustomUIFunc.cs#L27

-Tim

@Timothy_Logan1 Thanks for your debugging here, it definitely looks like a bug to me and is easy to see with this example. I’ll track this internally.

@Aparajit_Pratap any thoughts on this one?

I am facing the same Issue.May i ask is there any updates on this so far ?

Nono has reported this should be fixed in 2.0