Access NodeView or ViewModel from NodeModel

I have developed a node using the NodeModel implementation. To access data associated with the dynamo environment I added functionality to the NodeView where I was able to access nodeView.ViewModel.DynamoViewModel.Model

this allows me to pull the Version, File Name and File Path. The issue I am facing is this:

If a saved version of the script is opened, the NodeModel is instantiated first, causing values pulled from NodeView to be null and there is no way to force a re-calculation. In dynamo player, the NodeView is NEVER instantiated because the node is not visualized.

Is it possible to access the NodeView or the ViewModel from the NodeModel?

Taking another look today, what I need is a way to access the DynamoModel from the NodeModel

Have a look at this example: https://github.com/BadMonkeysTeam/Mandrill/blob/master/Mandrill_UI/NodeModels/MandrillWindowHtmlModel.cs

What you will see there is that when you create a

public class CustomNodeModelNodeViewCustomization : INodeViewCustomization<MandrillHtmlNodeModel>

Inside of the View Customization you have access to DynamoModel via NodeView. You can then pass it out to NodeModel like I am doing it with the call to

model.RequestSave += () => SaveMandrillWindow(model, nodeView);

…and accessing it there:

var graph = nodeView.ViewModel.DynamoViewModel.Model.CurrentWorkspace;

Cheers!

Thanks Konrad!

this is similar to what I have working now, the issue is that when Dynamo Player is used to run the node, the NodeView is never instantiated (or at least none of the breakpoints ive set there are hit) so I cannot pass the information back to the NodeModel to build my function call in BuildOutputAst.

I would need a way to get to the DynamoModel directly from the NodeModel to do this

Yeah, I see now. I would ask @Michael_Kirschner2 about this. I was not able to get Mandrill working on Dynamo Player because of that issue. Mike, ideas?

@Bzz will know more - but why do you need to get the DynamoModel?

@Michael_Kirschner2 the DynamoModel allows access to useful data unavailable anywhere else:

-Dynamo version
-CurrentWorkspace
-ForceRun()

to name a few

@rschmitt @Michael_Kirschner2 Dynamo Player only instantiates and uses the headless Dynamo without UI. View components are not going to be loaded including ViewModel. So for better compatibility with Dynamo Player a custom node will have to be designed in such way that its properties are accessible from headless Dynamo.

@Bzz Right… so what specifically do you suggest?

  • How, at the node level, can you tell if the node is being accessed headlessly?
  • How, when being run headlessly, can a Node identify properties about the file being executed and the version of dynamocore being used?
1 Like

The Dynamo file being executed could be hard coded into the graph as one work around. Doesn’t scale as well as actively pulling the data from the file though.

A total guess: For systems with multiple Dynamo builds, somewhere on the system Dynamo Player has a means of accessing the last version of Dynamo opened in the active session, and pulls that as the version to use when it launches. That info may contain the Dynamo Core version (or at least the Dynamo for Revit version, which should correlate to a core version).

correct, if you know the assembly location, it is pretty easy to get the version:

Assembly.LoadFile(@"C:\Program Files\Dynamo\Dynamo Core\2\DynamoCore.dll").GetName().Version.ToString()

But as you mentioned this, nor hard-coding the file name are not as scalable/trustworthy as accessing the info Dynamo clearly knows about itself but wont share

If you need access to the dynamoModel for properties which are not node specific I would write an extension.

http://developer.dynamobim.org/03-Development-Options/3-6-extensions.html

@Michael_Kirschner2 and @Bzz and use a View extension with dynamo player how exactly? On first glance it appears to fit into the same bucket of “Dynamo Player is headless”

you would want to use an extension (as opposed to a viewExtension) this will get loaded as normal.

Thanks @Michael_Kirschner2

are there any examples other than this?https://github.com/DynamoDS/DynamoSamples/blob/master/src/SampleExtension/Extension.cs

I can’t find much documentation on how to actually use/implement the extension, I tried constructing it within the node, but Ready never hits when debugging, leaving any value I try to collect from it as null

Extensions are not loaded or constructed inside nodes.
I linked some docs above, but that sample you linked is also pretty complete.

see this presentation for some older info:

@Michael_Kirschner2 the docs you linked previously are specific to view extensions, and now your advice to use an extension ignores everything I’ve asked about previously. I have nodes that need to know about the dynamomodel. Just say its not possible and be done with it. You and @Bzz pointing me to dead ends is a waste of both of our time. The best use of time would be for you all to actually care about implementing the basic functionality that devs ask for.

thinking about it more - it may not be possible to get access to the dynamoModel from within the extension either - so indeed a dead end :frowning: without reflection, which may also fail).

The design for nodeModels to have no access to the dynamoModel is intentional - but use in player came after that design. It is worth thinking about exposing a mechanism for this for use in player. But it’s also worth noting that the point of this separation is encourage use of application level plugins (extensions) for application level functionality, like version, location, file execution etc.

Could the node be directed to look at the content accessed by player, and read from there?
That is, ask player where it’s getting DynamoCore.dll from?