Zero Touch Node Socket invalidates after disconnect and reconnect

Got a rather simple Zero Touch Node, which basically generates a point triangle (I left the more complex parts out, as they are not used in this example anyways). First, this is the code:

public class Triangle
{
    /// <summary>
    /// All three Points that make up the Triangle. Tip is index 2
    /// </summary>
    public D.Point[] Points { get; private set; }
    public D.Vector Normal { get; private set; }

    private Triangle(D.Plane BasePlane, double Diameter)
    {

        D.Circle c = D.Circle.ByCenterPointRadiusNormal(BasePlane.Origin, Diameter, BasePlane.Normal);
        D.Polygon p = D.Polygon.RegularPolygon(c, 3);

        this.Points = p.Corners();
        this.Normal = BasePlane.Normal;
    }

    public static Triangle ByBasePlane(D.Plane BasePlane, double Diameter = 1.0)
    {
        return new Triangle(BasePlane, Diameter);
    }
}

Now, the node works fine, and shows as it should in Dynamo 2.8:

Clearly I must be doing something wrong code-wise, but I can’t make out what. Any clues highly appreciated!

when you disconnect the node, I think the points you return are disposed.

Your getter should return new points.

Don’t cache geometry that you later return into the graph.

I think we may have an attribute you can use to mark geometry as a long lived reference if you want to keep it safe from the DS garbage collector if you really need to do this for some reason.
@Aparajit_Pratap FYI.

1 Like

@aliasguru I think Mike is correct. The points and normal are getting disposed and when the getter is invoked again, there is nothing to return. Could you try using the [KeepReference] attribute on Points and Normal properties.

Alternatively as @Michael_Kirschner2 mentions you’ll need to create new points and normal in the getters.

Hi @Michael_Kirschner2 and @Aparajit_Pratap thanks for both of your replies. Seems like your advise that the Points might be disposed of after disconnection is spot on correct. I could not get the [KeepReference] attribute to work, the IDE complained about this parameter only being valid on Parameter declarations, so the following produces C# error CS0592:

    [R.KeepReference]
    public D.Vector Normal { get; private set; }

But, by simply defining a private property to hold the Point Array, and returning that from the Points property, the node behaves correctly. So this down low works:

    private D.Point[] points;

    /// <summary>
    /// All three Points that make up the Triangle. Tip is index 2
    /// </summary>
    public D.Point[] Points { get { return this.points; } }

whereas the following syntax shows the described behavior from the question:

    public D.Vector Normal { get; private set; }

worth noting that the same trick does not work with the Normal parameter, only with the Points[] Array.

Just marked @Michael_Kirschner2 initial post as the solution, this is the only method that consistently works.

when you return your points or your normal try translating them by (0,0,0) to make a copy.