Get out port data in Revit Api

Hi, I’m Revit api developer and I’m tring to develop a new add-in using Dynamo.
I run .dyn file with this code.

IDictionary<string, string> journalData = new Dictionary<string, string>
{
    {JournalKeys.ShowUiKey, false.ToString()},
    {JournalKeys.AutomationModeKey, true.ToString()},
    {"dynPath", dynPath},
    //{JournalKeys.DynPathKey, dynamoJournal},
    //{JournalKeys.DynPathExecuteKey, true.ToString()},
    {JournalKeys.ForceManualRunKey, true.ToString()},
    {JournalKeys.ModelShutDownKey, true.ToString()},
    //{JournalKeys.ModelNodesInfo, false.ToString()},
};

//get all loaded assemblies
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();

//find the Dynamo Revit one
var dynamoRevitApplication = loadedAssemblies
    .FirstOrDefault(a => a.FullName.Contains("DynamoRevitDS"));

//create our own instances of these things using reflection. Shoutout to BirdTools for helping with this.
object dInst = dynamoRevitApplication.CreateInstance("Dynamo.Applications.DynamoRevit");
object dta = dynamoRevitApplication.CreateInstance("Dynamo.Applications.DynamoRevitCommandData");
dta.GetType().GetProperty("Application").SetValue(dta, uiApp, null);
dta.GetType().GetProperty("JournalData").SetValue(dta, journalData, null);

object[] parameters = new object[] { dta };

dInst.GetType().GetMethod("ExecuteCommand").Invoke(dInst, parameters);

DynamoRevit.RevitDynamoModel.ForceRun();

foreach (NodeModel outputNode in DynamoRevit.RevitDynamoModel.CurrentWorkspace.Nodes.Where(x => x.IsSetAsOutput))
{

}

And I want to get out port data like next screen shots.
image

image

How can I get out port datas?

@baekdi

what do you mean by port data ? extracting X,Y,Z values ?

No, that means the “Outputs” data in Dynamo Player.

Hi @baekdi not sure i understand, is it as Andreas mention ? with the xyz value separate in players output ?

No, results vary depending on node type.

I can get that output values by this code :

foreach (PortModel outport in node.OutPorts)
{

    MirrorData mirror = node.GetValue(outport.Index, engine);
    var data = mirror?.Data;
}


//////////////////////////NodeModel Class////////////////////////////////
public MirrorData GetValue(int outPortIndex, EngineController engine)
{
    return engine.GetMirror(GetAstIdentifierForOutputIndex(outPortIndex).Value).GetData();
}


/////////////////////////////EngineController Class///////////////////////
/// <summary>
/// Returns runtime mirror for variable.
/// </summary>
/// <param name="variableName">Unique ID of AST node</param>
/// <returns>RuntimeMirror object that reflects status of a single designscript variable</returns>
public RuntimeMirror GetMirror(string variableName)
{
    lock (macroMutex)
    {
        RuntimeMirror mirror = null;
        try
        {
            mirror = liveRunnerServices.GetMirror(variableName, VerboseLogging);
        }
        catch (SymbolNotFoundException)
        {
            // The variable hasn't been defined yet. Just skip it. 
        }
        catch (Exception ex)
        {
            Log(string.Format(Properties.Resources.FailedToGetMirrorVariable, variableName,
                ex.Message));
        }

        return mirror;
    }
}

It can get value when the outport has a single value like summary of EngineController.GetMirror().

I can’t get outport values in list format.
How can i do?

Hi @baekdi

you can use the GetElements() method and the StringData property (MirrorData class)

a test in Revit 2025 (with macro)

C# Code
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Dynamo.Graph.Nodes;
using Dynamo.Applications;
using ProtoCore;
using Newtonsoft.Json;
using System.Dynamic;
using Dynamo.Configuration;
using Dynamo.Logging;
using System.Linq;

namespace LauncherScrit2
{
   [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
   [Autodesk.Revit.DB.Macros.AddInId("C234F93B-EFCB-4A43-AEB7-7F995E539D37")]
   public partial class ThisApplication
   {

      private static Dynamo.Engine.EngineController engine;
      // define logger variable
      private static DynamoLogger logger = new DynamoLogger(new DebugSettings(),
                                                    Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                                                    false,
                                                    false,
                                                    false);
      private void Module_Startup(object? sender, EventArgs e)
      {
      }

      private void Module_Shutdown(object? sender, EventArgs e)
      {
      }
      
      public void DynamoMacroRun()
      {
         UIDocument uidoc = this.ActiveUIDocument;  
         Document doc = this.ActiveUIDocument.Document;
         UIApplication uiApp = this;
         string resultOut = "";
         IDictionary<string, string> journalData = new Dictionary<string, string>
         {
            {JournalKeys.ShowUiKey, false.ToString()},
            {JournalKeys.AutomationModeKey, true.ToString()},
            {"dynPath", @"C:\Users\poupincyril\Documents\Test_Macro_Script.dyn"},
            //{JournalKeys.DynPathKey, dynamoJournal},
            //{JournalKeys.DynPathExecuteKey, true.ToString()},
            {JournalKeys.ForceManualRunKey, true.ToString()},
            {JournalKeys.ModelShutDownKey, true.ToString()},
            //{JournalKeys.ModelNodesInfo, false.ToString()},
         };

         //get all loaded assemblies
         var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();

         //find the Dynamo Revit one
         var dynamoRevitApplication = loadedAssemblies
            .FirstOrDefault(a => a.FullName.Contains("DynamoRevitDS"));

         //create our own instances of these things using reflection. Shoutout to BirdTools for helping with this.
         object dInst = dynamoRevitApplication.CreateInstance("Dynamo.Applications.DynamoRevit");
         object dta = dynamoRevitApplication.CreateInstance("Dynamo.Applications.DynamoRevitCommandData");
         dta.GetType().GetProperty("Application").SetValue(dta, uiApp, null);
         dta.GetType().GetProperty("JournalData").SetValue(dta, journalData, null);

         object[] parameters = new object[] { dta };

         dInst.GetType().GetMethod("ExecuteCommand").Invoke(dInst, parameters);

         Dynamo.Models.DynamoModel rdm = (Dynamo.Models.DynamoModel)dInst.GetType().GetProperty("RevitDynamoModel").GetValue(dInst, null);
         engine = rdm.EngineController;
         Dynamo.Graph.Workspaces.HomeWorkspaceModel wkspace = (Dynamo.Graph.Workspaces.HomeWorkspaceModel)rdm.CurrentWorkspace;
         logger?.Log("------------------------------------------", LogLevel.File);
         // suscribe node
         IEnumerable<Dynamo.Graph.Nodes.NodeModel> nodes = wkspace.Nodes;
         wkspace.Run();
         try
         {
            foreach (Dynamo.Graph.Nodes.NodeModel node in nodes)
            {
               if (node.IsSetAsOutput)
                  {
                     logger?.Log($"Process Node : {node.Name}", LogLevel.File);
                     foreach (Dynamo.Graph.Nodes.PortModel outport in node.OutPorts)
                        {
                           ProtoCore.Mirror.MirrorData mirror = node.GetValue(outport.Index, engine);
                           IEnumerable<string> valuesData = mirror.GetElements().Select(p => p.StringData);
                           string json3 = JsonConvert.SerializeObject(new object[] { node.Name, valuesData}, Formatting.Indented);
                           resultOut += "\n" + json3;
                           logger?.Log(json3, LogLevel.File);
                        }
                  }
            }
            TaskDialog dialog = new TaskDialog("Dynamo");
            dialog.MainInstruction =  "Run Success";
            dialog.ExpandedContent = resultOut;
            dialog.Show();
            
         }
         catch (Exception ex)
         {
               logger?.LogError(ex.Message);
               TaskDialog.Show("Dynamo", "Run Failed");
         } 
      }
   }
}
1 Like