I am getting a problem with the view template node from Archilab @Konrad_K_Sobon. Before I run it, it displays fine. After I run it, I get a duplicate output port and an error:
Warning: Dictionary.ByKeysValues operation failed.
An element with the same key but a different value already exists. Key: viewTemplate
I have seen this when the version of the package is not compatible / meant for the version of Dynamo you are running, and most often the package is older. I would try to install a newer version of archi-lab and see since the 2018.13.13 is quite a ways down the list for this package.
I think it might be the other way around though - using a newer package on Revit 2018. Maybe I need to use an older version of Archilab, like 2018.13.1.3 instead of 2019.2.6, if I’m still on Revit 2018.
Hmm. Monocle shouldn’t be causing duplicate output ports. I do see that you have a fairly old version of Archi-Lab that is most likely not built for Dynamo 2.0. I would try to get that updated to the latest version of 2019.2.26 and see if it fixes.
*edit: didn’t see the other replies because I replied from email. lol
Definitely get that package updated and see if it helps.
For monocle’s error that is popping up. That’s different and related to Dynamo loading an older version of a DLL that I also used. I’ll see if I can get that revised here soon. (Unfortunately that means I have to use an old version of that dependency too.)
@Paul_Wintour the issue is just what @SeanP mentioned. You are using the version of the package that was built against the Dynamo 1.3 which didn’t use the new JSON based schema, and doesn’t have a proper constructors.
Now, I see that you went with that version because you want to use it with Revit 2018, but in this case I think its safe to use versions starting with 2019 (built against Revit 2019 API). Why? Because if there is a node in my package that uses any of the new APIs from Revit, it would simply not work, but rest of the package will work just fine, and they were all built against Dynamo 2.0 and higher so no duplicate ports there. You might get a warning that my package is looking for Revit 2019 dlls, but again, if Revit 2018 dlls are available, then it should all work, unless API specific to 2019 is used by a node.
So, please always use the LATEST package. Revit API version it was built against is a smaller concern than version of Dynamo you are on.
Thanks @Konrad_K_Sobon & @SeanP. I though I had the latest but that was for the Dynamo 2.1 library, not Dynamo 2.0 library. Updating fixed the issue. Thanks again
Since the GeoJSON.Net package is open source, I created a new onBIM.GeoJSON.NET project in my solution and added all the code from the original. In this new project I installed NewtonSoft 8.0.3 and the project was compiled normally.
However, as you can see in the image below, the problem of duplicated ports continues, but now the Warning is different. However, I still don’t understand why this is still happening since all projects within my solution have Newtonsoft 8.0.3 installed.
After a hellish dll saga and a “few” hours of headache, everything worked fine now.
Main actions that were taken:
I copied all the code from the GeoJSON.Net package to my project in order to eliminate the dependency on a Newtonsoft version not compatible with Dynamo.
Instead of using an abstract class to implement my NodeModel DropDown, I implemented it directly.
The idea of having an abstract class was to generalize the construction of other DropDowns, but it didn’t work out because it was necessary to pass the Enum Type and Parse Func as parameters. This caused abnormal behavior where DropDown only worked the second time the file was opened. Which then made sense to me, because it seems that in the first round the node was created by one constructor, then by another.
I created [JsonConstructor] as recommended.
Old code:
using Dynamo.Graph.Nodes;
using Newtonsoft.Json;
using System;
namespace NodeModels
{
[NodeName("Elevation Types")]
[NodeDescription("onBIM nodes GIS Elevation types to be used in GeoJSON geometry conversion to Dynamo")]
[NodeCategory("onBIM Nodes.GIS")]
[OutPortNames("ElevationType")]
[OutPortTypes("onBIMNodes.GIS.ElevationType")]
[OutPortDescriptions("Selected ElevationType")]
[IsDesignScriptCompatible]
public class ElevationTypesDropDown : CustomGenericEnumerationDropDown //old abstract class
{
public ElevationTypesDropDown() : base()
{
EnumerationType = typeof(onBIMNodes.GIS.ElevationType);
EnumParseFunction = NodeModelsFunctions.ElevationTypesDropDownFunctions.ParseElevationType;
}
}
}
new code:
using CoreNodeModels;
using Dynamo.Graph.Nodes;
using Dynamo.Utilities;
using Newtonsoft.Json;
using ProtoCore.AST.AssociativeAST;
using System;
using System.Collections.Generic;
using System.Linq;
namespace NodeModels
{
/// <summary>
/// Generic UI Dropdown node baseclass for Enumerations.
/// This class populates a dropdown with all enumeration values of the specified type.
/// </summary>
[NodeName("Elevation Types")]
[NodeDescription("onBIMNodes GIS Elevation types to be used in GeoJSON geometry conversion to Dynamo")]
[NodeCategory("onBIM Nodes.GIS")]
[OutPortDescriptions("Selected ElevationType")]
[IsDesignScriptCompatible]
public class ElevationTypesDropDown : DSDropDownBase
{
public ElevationTypesDropDown() : base("ElevationType") { }
[JsonConstructor]
public ElevationTypesDropDown(
IEnumerable<PortModel> inPorts,
IEnumerable<PortModel> outPorts
) : base("ElevationType", inPorts,outPorts) { }
protected override CoreNodeModels.DSDropDownBase.SelectionState PopulateItemsCore(string currentSelection)
{
PopulateDropDownItems();
return SelectionState.Restore;
}
/// <summary>
/// Populate Items in Dropdown menu
/// </summary>
public void PopulateDropDownItems()
{
Type EnumerationType = typeof(onBIMNodes.GIS.ElevationType);
// Clear the dropdown list
Items.Clear();
// Get all enumeration names and add them to the dropdown menu
foreach (string name in Enum.GetNames(EnumerationType))
{
Items.Add(new CoreNodeModels.DynamoDropDownItem(name, Enum.Parse(EnumerationType, name)));
}
Items = Items.OrderBy(x => x.Name).ToObservableCollection();
// Prevent node to raise a Warning when Dynamo script is in Automatic mode
// by Selecting the list first item
SelectedIndex = 0;
}
/// <summary>
/// Assign the selected Enumeration value to the output
/// </summary>
public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
{
Func<string, object> EnumParseFunction = NodeModelsFunctions.ElevationTypesDropDownFunctions.ParseElevationType;
// get the selected item name
var stringNode = AstFactory.BuildStringNode((string)Items[SelectedIndex].Name);
var args = new List<AssociativeNode>();
args.Add(stringNode);
var functionCall = AstFactory.BuildFunctionCall(EnumParseFunction, args);
// assign the selected name to an actual enumeration value
var assign = AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), functionCall);
// return the enumeration value
return new List<AssociativeNode> { assign };
}
}
}