diff --git a/src/DynamoApplications/StartupUtils.cs b/src/DynamoApplications/StartupUtils.cs index 134fbe7afb4..b30ed9eb450 100644 --- a/src/DynamoApplications/StartupUtils.cs +++ b/src/DynamoApplications/StartupUtils.cs @@ -87,6 +87,8 @@ public static CommandLineArguments Parse(string[] args) // Generate geometry json file var geometryFilePath = string.Empty; + // dll paths we'll import before running a graph + var importPaths = new List() ; bool showHelp = false; var optionsSet = new OptionSet().Add("o=|O=", "OpenFilePath, Instruct Dynamo to open headless and run a dyn file at this path", o => openfilepath = o) @@ -97,7 +99,9 @@ public static CommandLineArguments Parse(string[] args) .Add("x|X", "When used in combination with the 'O' flag, opens a .dyn file from the specified path and converts it to .json." + "File will have the .json extension and be located in the same directory as the original file.", x => convertFile = x != null) .Add("h|H|help", "Get some help", h => showHelp = h != null) - .Add("g=|G=|geometry", "Geometry, Instruct Dynamo to output geometry from all evaluations to a json file at this path", g => geometryFilePath = g); + .Add("g=|G=|geometry", "Geometry, Instruct Dynamo to output geometry from all evaluations to a json file at this path", g => geometryFilePath = g) + .Add("i=|I=|import", "Import, Instruct Dynamo to import an assembly as a node library. This argument should be a filepath to a single .dll" + + " - if you wish to import multiple dlls - use this flag multiple times: -i 'assembly1.dll' -i 'assembly2.dll' ", i=>importPaths.Add(i)); optionsSet.Parse(args); @@ -118,7 +122,8 @@ public static CommandLineArguments Parse(string[] args) OpenFilePath = openfilepath, Verbose = verbose, ConvertFile = convertFile, - GeometryFilePath = geometryFilePath + GeometryFilePath = geometryFilePath, + ImportedPaths = importPaths }; } @@ -134,6 +139,7 @@ private static void ShowHelp(OptionSet opSet) public string Verbose { get; set; } public bool ConvertFile { get; set; } public string GeometryFilePath { get; set; } + public IEnumerable ImportedPaths { get; set; } } public static void PreloadShapeManager(ref string geometryFactoryPath, ref string preloaderLocation) diff --git a/src/DynamoCLI/CommandLineRunner.cs b/src/DynamoCLI/CommandLineRunner.cs index 765703c1aa4..b2093b99dd6 100644 --- a/src/DynamoCLI/CommandLineRunner.cs +++ b/src/DynamoCLI/CommandLineRunner.cs @@ -44,6 +44,12 @@ private static XmlDocument RunCommandLineArgs(DynamoModel model, StartupUtils.Co Console.WriteLine("geometryFilePath option is only available when running DynamoWPFCLI, not DynamoCLI"); } + cmdLineArgs.ImportedPaths.ToList().ForEach(path => + { + ImportAssembly(model, path); + + }); + model.OpenFileFromPath(cmdLineArgs.OpenFilePath, true); Console.WriteLine("loaded file"); model.EvaluationCompleted += (o, args) => { evalComplete = true; }; @@ -79,6 +85,33 @@ private static XmlDocument RunCommandLineArgs(DynamoModel model, StartupUtils.Co return doc; } + /// + /// Attempts to import an assembly as a node library from a given file path. + /// + /// + /// + protected static void ImportAssembly(DynamoModel model, string path) + { + try + { + var filePath = new System.IO.FileInfo(path); + if (!filePath.Exists) + { + Console.WriteLine($"could not find requested import library at path{path}"); + } + else + { + Console.WriteLine($"attempting to import assembly {path}"); + var assembly = System.Reflection.Assembly.LoadFile(path); + model.LoadNodeLibrary(assembly); + } + } + catch (Exception e) + { + Console.WriteLine($"exception while trying to load assembly {path}: {e}"); + } + } + protected static string GetStringRepOfCollection(ProtoCore.Mirror.MirrorData value) { var items = string.Join(",", diff --git a/src/DynamoWPFCLI/CommandLineRunnerWPF.cs b/src/DynamoWPFCLI/CommandLineRunnerWPF.cs index 40f9f5ac295..bfe7f378d3b 100644 --- a/src/DynamoWPFCLI/CommandLineRunnerWPF.cs +++ b/src/DynamoWPFCLI/CommandLineRunnerWPF.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading; using System.Xml; using Dynamo.Applications; @@ -39,6 +40,11 @@ private static XmlDocument RunCommandLineArgs(DynamoViewModel viewModel, Startup Console.WriteLine("commandFilePath option is only available when running DynamoSandbox, not DynamoWPFCLI"); } + cmdLineArgs.ImportedPaths.ToList().ForEach(path => + { + ImportAssembly(viewModel.Model, path); + }); + viewModel.OpenCommand.Execute(new Tuple(cmdLineArgs.OpenFilePath, true)); Console.WriteLine("loaded file"); viewModel.Model.EvaluationCompleted += (o, args) => { evalComplete = true; }; diff --git a/test/Libraries/CommandLineTests/CommandLineTests.cs b/test/Libraries/CommandLineTests/CommandLineTests.cs index a18edc3acde..3690e63cb40 100644 --- a/test/Libraries/CommandLineTests/CommandLineTests.cs +++ b/test/Libraries/CommandLineTests/CommandLineTests.cs @@ -12,6 +12,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Dynamo.Wpf.ViewModels.Watch3D; +using System.Reflection; namespace Dynamo.Tests { @@ -19,6 +20,13 @@ internal class CommandLineTests : DynamoModelTestBase { protected override void GetLibrariesToPreload(List libraries) { + libraries.Add("VMDataBridge.dll"); + libraries.Add("DesignScriptBuiltin.dll"); + libraries.Add("DSCoreNodes.dll"); + libraries.Add("FunctionObject.ds"); + libraries.Add("BuiltIn.ds"); + libraries.Add("ProtoGeometry.dll"); + base.GetLibrariesToPreload(libraries); } @@ -52,12 +60,14 @@ protected static StartupUtils.CommandLineArguments CommandstringToArgs(string co return args; } + //Only for use during testing. Windows or Posix will handle this when invoking commands. protected static string[] CommandStringToStringArray(string commandString) { //convert string to commandlineargs, var m = Regex.Matches(commandString, "([^\"]\\S*|\".+?\")\\s*"); - var list = m.Cast().Select(match => match.Value).ToList(); - + var list = m.Cast().Select(match => match.Value); + //trim off leading and trailing "'s - this is handy when paths are passed as args with quotes around them. + list = list.Select(arg => arg.Trim(new[] { '"' })).ToList(); //strip trailing whitespace var argarray = list.Select(x => x.Trim()).ToArray(); return argarray.ToArray(); @@ -78,6 +88,63 @@ public void CanOpenAndRunDynamoModelWithCommandLineRunner() AssertPreviewValue("4c5889ac-7b91-4fb5-aaad-a2128b533279", 4.0); } + [Test] + public void ImportingAnAssemblyDoesNotEffectCustomNodePaths() + { + //load a graph which requires first loading FFITarget.dll + var openpath = Path.Combine(TestDirectory, @"core\commandLine\FFITarget.dyn"); + var importPath = Path.Combine(ExecutingDirectory, "FFITarget.dll"); + + var runner = new DynamoCLI.CommandLineRunner(this.CurrentDynamoModel); + string commandstring = $"/o {openpath} /i {importPath}"; + + runner.Run(CommandstringToArgs(commandstring)); + //assert that the FFITarget dummy point node is created with correct properties. + AssertPreviewValue("fba565f89c8948e290bbb423177fa7bb", 2.0); + AssertPreviewValue("5a1fae3e13ce4ccfba737ec75057907b", 2.0); + + //the custom package paths should not be effected by running the CLI. + this.CurrentDynamoModel.PreferenceSettings.CustomPackageFolders.ForEach(packagePath => + { + Assert.IsFalse(packagePath.Contains(importPath) || packagePath == importPath); + }); + + } + + [Test] + public void CanImportDependencyBeforeRunningGraph() + { + //load a graph which requires first loading FFITarget.dll + var openpath = Path.Combine(TestDirectory, @"core\commandLine\FFITarget.dyn"); + var importPath = Path.Combine(ExecutingDirectory, "FFITarget.dll"); + + var runner = new DynamoCLI.CommandLineRunner(this.CurrentDynamoModel); + string commandstring = $"/o {openpath} /i {importPath}"; + + runner.Run(CommandstringToArgs(commandstring)); + //assert that the FFITarget dummy point node is created with correct properties. + AssertPreviewValue("fba565f89c8948e290bbb423177fa7bb", 2.0); + AssertPreviewValue("5a1fae3e13ce4ccfba737ec75057907b", 2.0); + + } + + [Test] + public void CanImportMultipleDepsBeforeRunningGraph() + { + //load a graph which requires first loading FFITarget.dll and SampleLibraryZeroTouch.dll + var openpath = Path.Combine(TestDirectory, @"core\commandLine\multipleDeps.dyn"); + var importPath1 = Path.Combine(ExecutingDirectory, "FFITarget.dll"); + var importPath2 = Path.Combine(TestDirectory,"pkgs", "Dynamo Samples","bin" ,"SampleLibraryZeroTouch.dll"); + + var runner = new DynamoCLI.CommandLineRunner(this.CurrentDynamoModel); + string commandstring = $"/o {openpath} /i {importPath1} /i \"{importPath2}\""; + + runner.Run(CommandstringToArgs(commandstring)); + //assert that this node from the samples ZT dll produces a correct result. + AssertPreviewValue("04c1531865e34ecb80a265c7822450aa", "Point(X = 4.000, Y = 2.000, Z = 2.000)" ); + + } + [Test] public void CanOpenAndRunFileWihtListsCorrectlyToOutputFileFromDynamoCLIexe() { diff --git a/test/core/commandline/FFITarget.dyn b/test/core/commandline/FFITarget.dyn new file mode 100644 index 00000000000..f2d9a77c519 --- /dev/null +++ b/test/core/commandline/FFITarget.dyn @@ -0,0 +1,224 @@ +{ + "Uuid": "9f036fac-5f6d-4d42-ae3e-dcba834f38d0", + "IsCustomNode": false, + "Description": null, + "Name": "FFITarget", + "ElementResolver": { + "ResolutionMap": {} + }, + "Inputs": [], + "Outputs": [], + "Nodes": [ + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "NodeType": "FunctionNode", + "FunctionSignature": "FFITarget.DummyPoint2D.ByCoordinates@double,double", + "Id": "dcaa059e5b284b55b9a2de81060ae21f", + "Inputs": [ + { + "Id": "1cdf99077dae4ceab28b9fa4f5d5ebee", + "Name": "x", + "Description": "double", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "efcf8f1815374aa9a91259daa1843a38", + "Name": "y", + "Description": "double", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "26af6be0393c40b192e52386d20b0b6c", + "Name": "DummyPoint2D", + "Description": "DummyPoint2D", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Auto", + "Description": "DummyPoint2D.ByCoordinates (x: double, y: double): DummyPoint2D" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "NodeType": "FunctionNode", + "FunctionSignature": "FFITarget.DummyPoint2D.X", + "Id": "fba565f89c8948e290bbb423177fa7bb", + "Inputs": [ + { + "Id": "e3f5045323774bb385962f6b9a6720d7", + "Name": "dummyPoint2D", + "Description": "FFITarget.DummyPoint2D", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "4ad83b9c20fc4ab3867fec0850312eb0", + "Name": "double", + "Description": "double", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Auto", + "Description": "DummyPoint2D.X: double" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "NodeType": "FunctionNode", + "FunctionSignature": "FFITarget.DummyPoint2D.Y", + "Id": "5a1fae3e13ce4ccfba737ec75057907b", + "Inputs": [ + { + "Id": "9a495555dbcf40618ad88b3032d421d9", + "Name": "dummyPoint2D", + "Description": "FFITarget.DummyPoint2D", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "af3d1a3b5bfc4b8b98945576641b07d5", + "Name": "double", + "Description": "double", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Auto", + "Description": "DummyPoint2D.Y: double" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "NodeType": "CodeBlockNode", + "Code": "2;", + "Id": "e6f1c81d062e4dda9c03c5a7e8301048", + "Inputs": [], + "Outputs": [ + { + "Id": "46c95cbd6dfe47259e7b30c38601e2bb", + "Name": "", + "Description": "Value of expression at line 1", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Allows for DesignScript code to be authored directly" + } + ], + "Connectors": [ + { + "Start": "26af6be0393c40b192e52386d20b0b6c", + "End": "9a495555dbcf40618ad88b3032d421d9", + "Id": "c8c21293596b4e2fb7c4d53f28a2f8ca" + }, + { + "Start": "26af6be0393c40b192e52386d20b0b6c", + "End": "e3f5045323774bb385962f6b9a6720d7", + "Id": "8a96b6f11e7843b6983e3772e6768d73" + }, + { + "Start": "46c95cbd6dfe47259e7b30c38601e2bb", + "End": "1cdf99077dae4ceab28b9fa4f5d5ebee", + "Id": "791e810687854dfc88c05ca89154d181" + }, + { + "Start": "46c95cbd6dfe47259e7b30c38601e2bb", + "End": "efcf8f1815374aa9a91259daa1843a38", + "Id": "bffc4b208df54b6a8b3e14b2d5bc2985" + } + ], + "Dependencies": [], + "Bindings": [], + "View": { + "Dynamo": { + "ScaleFactor": 1.0, + "HasRunWithoutCrash": true, + "IsVisibleInDynamoLibrary": true, + "Version": "2.2.0.3675", + "RunType": "Automatic", + "RunPeriod": "1000" + }, + "Camera": { + "Name": "Background Preview", + "EyeX": -17.0, + "EyeY": 24.0, + "EyeZ": 50.0, + "LookX": 12.0, + "LookY": -13.0, + "LookZ": -58.0, + "UpX": 0.0, + "UpY": 1.0, + "UpZ": 0.0 + }, + "NodeViews": [ + { + "ShowGeometry": true, + "Name": "DummyPoint2D.ByCoordinates", + "Id": "dcaa059e5b284b55b9a2de81060ae21f", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 328.5, + "Y": 286.25 + }, + { + "ShowGeometry": true, + "Name": "DummyPoint2D.X", + "Id": "fba565f89c8948e290bbb423177fa7bb", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 599.5, + "Y": 201.25 + }, + { + "ShowGeometry": true, + "Name": "DummyPoint2D.Y", + "Id": "5a1fae3e13ce4ccfba737ec75057907b", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 604.5, + "Y": 344.25 + }, + { + "ShowGeometry": true, + "Name": "Code Block", + "Id": "e6f1c81d062e4dda9c03c5a7e8301048", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 203.0, + "Y": 198.0 + } + ], + "Annotations": [], + "X": 0.0, + "Y": 0.0, + "Zoom": 1.0 + } +} \ No newline at end of file diff --git a/test/core/commandline/multipleDeps.dyn b/test/core/commandline/multipleDeps.dyn new file mode 100644 index 00000000000..317100879e7 --- /dev/null +++ b/test/core/commandline/multipleDeps.dyn @@ -0,0 +1,445 @@ +{ + "Uuid": "9f036fac-5f6d-4d42-ae3e-dcba834f38d0", + "IsCustomNode": false, + "Description": null, + "Name": "multipleDeps", + "ElementResolver": { + "ResolutionMap": {} + }, + "Inputs": [], + "Outputs": [], + "Nodes": [ + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "NodeType": "FunctionNode", + "FunctionSignature": "FFITarget.DummyPoint2D.ByCoordinates@double,double", + "Id": "dcaa059e5b284b55b9a2de81060ae21f", + "Inputs": [ + { + "Id": "1cdf99077dae4ceab28b9fa4f5d5ebee", + "Name": "x", + "Description": "double", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "efcf8f1815374aa9a91259daa1843a38", + "Name": "y", + "Description": "double", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "26af6be0393c40b192e52386d20b0b6c", + "Name": "DummyPoint2D", + "Description": "DummyPoint2D", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Auto", + "Description": "DummyPoint2D.ByCoordinates (x: double, y: double): DummyPoint2D" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "NodeType": "FunctionNode", + "FunctionSignature": "FFITarget.DummyPoint2D.X", + "Id": "fba565f89c8948e290bbb423177fa7bb", + "Inputs": [ + { + "Id": "e3f5045323774bb385962f6b9a6720d7", + "Name": "dummyPoint2D", + "Description": "FFITarget.DummyPoint2D", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "4ad83b9c20fc4ab3867fec0850312eb0", + "Name": "double", + "Description": "double", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Auto", + "Description": "DummyPoint2D.X: double" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "NodeType": "FunctionNode", + "FunctionSignature": "FFITarget.DummyPoint2D.Y", + "Id": "5a1fae3e13ce4ccfba737ec75057907b", + "Inputs": [ + { + "Id": "9a495555dbcf40618ad88b3032d421d9", + "Name": "dummyPoint2D", + "Description": "FFITarget.DummyPoint2D", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "af3d1a3b5bfc4b8b98945576641b07d5", + "Name": "double", + "Description": "double", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Auto", + "Description": "DummyPoint2D.Y: double" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "NodeType": "CodeBlockNode", + "Code": "2;", + "Id": "e6f1c81d062e4dda9c03c5a7e8301048", + "Inputs": [], + "Outputs": [ + { + "Id": "46c95cbd6dfe47259e7b30c38601e2bb", + "Name": "", + "Description": "Value of expression at line 1", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Allows for DesignScript code to be authored directly" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "NodeType": "FunctionNode", + "FunctionSignature": "Examples.NEWBasicExample.Create@double,double,double", + "Id": "50359ed1ca3046ed8ba41d69e07348ad", + "Inputs": [ + { + "Id": "4203ae945fc44d3eb51c7f90941558f9", + "Name": "x", + "Description": "double\nDefault value : 42", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "3223ddcfee1a41d3b432d6cb80a303c1", + "Name": "y", + "Description": "double\nDefault value : 42", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "d8250214d2284325af98a45b3a0e8d3e", + "Name": "z", + "Description": "double\nDefault value : 42", + "UsingDefaultValue": true, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "f7bccd52095444f4b5b47b9991cd044e", + "Name": "NEWBasicExample", + "Description": "NEWBasicExample", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Auto", + "Description": "NEWBasicExample.Create (x: double = 42, y: double = 42, z: double = 42): NEWBasicExample" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore", + "NodeType": "FunctionNode", + "FunctionSignature": "Examples.NEWBasicExample.Point", + "Id": "065d5eb799ab4cd5897a6dc224c62b76", + "Inputs": [ + { + "Id": "8517fc12332d47afabf36b9d9ec25831", + "Name": "nEWBasicExample", + "Description": "Examples.NEWBasicExample", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "d889e122ea1e4d6d8ec4537c47639489", + "Name": "Point", + "Description": "Point", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Auto", + "Description": "NEWBasicExample.Point: Point" + }, + { + "ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore", + "NodeType": "CodeBlockNode", + "Code": "x+y;", + "Id": "a62f2d313a1a4dbbba5dbf3eed9bbcfa", + "Inputs": [ + { + "Id": "344bcd11e2394669b2510a479a37101a", + "Name": "x", + "Description": "x", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + }, + { + "Id": "d6b9a514f023496dafb6c1bcbcbaf3c7", + "Name": "y", + "Description": "y", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "f35629641cf94067aa3de706c7272e5c", + "Name": "", + "Description": "Value of expression at line 1", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Allows for DesignScript code to be authored directly" + }, + { + "ConcreteType": "CoreNodeModels.FromObject, CoreNodeModels", + "NodeType": "ExtensionNode", + "Id": "04c1531865e34ecb80a265c7822450aa", + "Inputs": [ + { + "Id": "deb0d650a5434ddb8312dff0954b7c80", + "Name": "obj", + "Description": "Object to be serialized", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Outputs": [ + { + "Id": "2cebea23b84a4ec5b92c1fec3b865bd7", + "Name": "str", + "Description": "Result of math computation", + "UsingDefaultValue": false, + "Level": 2, + "UseLevels": false, + "KeepListStructure": false + } + ], + "Replication": "Disabled", + "Description": "Convert an object to a string representation." + } + ], + "Connectors": [ + { + "Start": "26af6be0393c40b192e52386d20b0b6c", + "End": "9a495555dbcf40618ad88b3032d421d9", + "Id": "c8c21293596b4e2fb7c4d53f28a2f8ca" + }, + { + "Start": "26af6be0393c40b192e52386d20b0b6c", + "End": "e3f5045323774bb385962f6b9a6720d7", + "Id": "8a96b6f11e7843b6983e3772e6768d73" + }, + { + "Start": "4ad83b9c20fc4ab3867fec0850312eb0", + "End": "344bcd11e2394669b2510a479a37101a", + "Id": "54050ec3158641ae8432b639bcd064fd" + }, + { + "Start": "af3d1a3b5bfc4b8b98945576641b07d5", + "End": "d6b9a514f023496dafb6c1bcbcbaf3c7", + "Id": "4b7b2db4cc4e4956aad2c0b20814bdd9" + }, + { + "Start": "46c95cbd6dfe47259e7b30c38601e2bb", + "End": "1cdf99077dae4ceab28b9fa4f5d5ebee", + "Id": "791e810687854dfc88c05ca89154d181" + }, + { + "Start": "46c95cbd6dfe47259e7b30c38601e2bb", + "End": "efcf8f1815374aa9a91259daa1843a38", + "Id": "bffc4b208df54b6a8b3e14b2d5bc2985" + }, + { + "Start": "46c95cbd6dfe47259e7b30c38601e2bb", + "End": "3223ddcfee1a41d3b432d6cb80a303c1", + "Id": "3db5360d0428447c96706c55217b48ca" + }, + { + "Start": "46c95cbd6dfe47259e7b30c38601e2bb", + "End": "d8250214d2284325af98a45b3a0e8d3e", + "Id": "797ba95c6b7d465ebef73c77bb8ce746" + }, + { + "Start": "f7bccd52095444f4b5b47b9991cd044e", + "End": "8517fc12332d47afabf36b9d9ec25831", + "Id": "3d2ca62916864cefa96336c7b11922f2" + }, + { + "Start": "d889e122ea1e4d6d8ec4537c47639489", + "End": "deb0d650a5434ddb8312dff0954b7c80", + "Id": "0dad12314eb346a2a9563376d326848f" + }, + { + "Start": "f35629641cf94067aa3de706c7272e5c", + "End": "4203ae945fc44d3eb51c7f90941558f9", + "Id": "4493c4acb71f411596093f97d384344e" + } + ], + "Dependencies": [], + "Bindings": [], + "View": { + "Dynamo": { + "ScaleFactor": 1.0, + "HasRunWithoutCrash": true, + "IsVisibleInDynamoLibrary": true, + "Version": "2.2.0.3675", + "RunType": "Automatic", + "RunPeriod": "1000" + }, + "Camera": { + "Name": "Background Preview", + "EyeX": -17.0, + "EyeY": 24.0, + "EyeZ": 50.0, + "LookX": 12.0, + "LookY": -13.0, + "LookZ": -58.0, + "UpX": 0.0, + "UpY": 1.0, + "UpZ": 0.0 + }, + "NodeViews": [ + { + "ShowGeometry": true, + "Name": "DummyPoint2D.ByCoordinates", + "Id": "dcaa059e5b284b55b9a2de81060ae21f", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 273.5, + "Y": 214.25 + }, + { + "ShowGeometry": true, + "Name": "DummyPoint2D.X", + "Id": "fba565f89c8948e290bbb423177fa7bb", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 597.5, + "Y": 126.25 + }, + { + "ShowGeometry": true, + "Name": "DummyPoint2D.Y", + "Id": "5a1fae3e13ce4ccfba737ec75057907b", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 591.5, + "Y": 252.25 + }, + { + "ShowGeometry": true, + "Name": "Code Block", + "Id": "e6f1c81d062e4dda9c03c5a7e8301048", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 124.0, + "Y": 230.0 + }, + { + "ShowGeometry": true, + "Name": "NEWBasicExample.Create", + "Id": "50359ed1ca3046ed8ba41d69e07348ad", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 1011.5, + "Y": 266.25 + }, + { + "ShowGeometry": true, + "Name": "NEWBasicExample.Point", + "Id": "065d5eb799ab4cd5897a6dc224c62b76", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 1286.5, + "Y": 273.25 + }, + { + "ShowGeometry": true, + "Name": "Code Block", + "Id": "a62f2d313a1a4dbbba5dbf3eed9bbcfa", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 896.0, + "Y": 191.0 + }, + { + "ShowGeometry": true, + "Name": "String from Object", + "Id": "04c1531865e34ecb80a265c7822450aa", + "IsSetAsInput": false, + "IsSetAsOutput": false, + "Excluded": false, + "X": 1392.5, + "Y": 363.25 + } + ], + "Annotations": [], + "X": -470.0, + "Y": 10.0, + "Zoom": 1.0 + } +} \ No newline at end of file