Serialising and deserialising a custom type for Grasshopper

Hi,

I’m having trouble serialising and deserialising a custom type that I have made for Grassopper.
It’s specifically the reading that seems to be the issue. When I’m debugging with VS Read never seems to get called. Whereas Write gets called regularly. I can also confirm that everything is being properly written when inspecting the .gh file. I’m just not sure though why Read wouldn’t get called.

Also I’ve chosen to inherit from the IGH_GeometricGoo interface instead of GH_GeometricGoo<T> not sure if that might have anything to do with it.

Below I have a shortened excerpt of the class and specifically the two methods.

public class Manipulator : IGH_GeometricGoo
{

    public bool Read(GH_IReader reader)
    {
        this.Name = reader.GetString("Name");
        this.Manufacturer = (Manufacturer)reader.GetInt32("Manufacturer");

        Plane bPlane = new Plane();
        GH_Convert.ToPlane(reader.GetPlane("RobBasePlane"), ref bPlane, GH_Conversion.Both);
        this.RobBasePlane = bPlane

        return true;

    }
    public bool Write(GH_IWriter writer)
    {
        GH_Plane gH_RobBasePlane = new GH_Plane(this.RobBasePlane);

        writer.SetString("Name", this.Name);
        writer.SetInt32("Manufacturer", (int)this.Manufacturer);
        gH_RobBasePlane.Write(writer.CreateChunk("RobBasePlane"));

    return true;
    }
}

If you want to store custom types within the definition file, you will need to implement your own GH_PersistentParam, otherwise the type would stay run-time.

2 Likes

Hey @gankeyu,

thanks for the feedback. I have now tiered implementing a GH_PersistentParam class. But I still seem to have the same issues, of not even being able to copy data. The issue seems similar to:

but so far I’ve not been able to spot a mis match between my Write and Read methods.

Here is my new Param class:

public class Param_Manipulator : GH_PersistentParam<Manipulator>
{
    public Param_Manipulator()
      : base("Axis Robot", "Axis Robot", "This parampeter will store Axis Robots and their data.", Axis.AxisInfo.Plugin, Axis.AxisInfo.TabCore)
    { }

    public override Guid ComponentGuid => new Guid("17C49BD4-7A54-4471-961A-B5E0E971F7F4");

    protected override Manipulator InstantiateT()
    {
        return Manipulator.Default;
    }
    protected override GH_GetterResult Prompt_Singular(ref Manipulator value)
    {
        Rhino.Input.Custom.GetOption go = new Rhino.Input.Custom.GetOption();
        go.SetCommandPrompt("Set default Robot");
        go.AcceptNothing(true);
        go.AddOption("True");

        switch (go.Get())
        {
            case Rhino.Input.GetResult.Option:
                if (go.Option().EnglishName == "True") { value = Manipulator.Default; }
                return GH_GetterResult.success;

            case Rhino.Input.GetResult.Nothing:
                return GH_GetterResult.accept;

            default:
                return GH_GetterResult.cancel;
        }

        return GH_GetterResult.cancel;
    }
    protected override GH_GetterResult Prompt_Plural(ref List<Manipulator> values)
    {
        return GH_GetterResult.cancel;
    }
    public override void AppendAdditionalMenuItems(ToolStripDropDown menu)
    {
        //Menu_AppendItem(menu, "Set the default value", SetDefaultHandler, SourceCount == 0);
        base.AppendAdditionalMenuItems(menu);
    }
    private void SetDefaultHandler(object sender, EventArgs e)
    {
        PersistentData.Clear();
        PersistentData.Append(Manipulator.Default, new GH_Path(0));
        ExpireSolution(true);
    }
    public override bool Write(GH_IWriter writer)
    {
        PersistentData.Write(writer);
        return base.Write(writer);
    }
    public override bool Read(GH_IReader reader)
    {
        SetPersistentData(Manipulator.Default);            
        return base.Read(reader);
    }
}

I know that I’m currently just setting a default, but that also just returns null as of now.
On the other hand the SetDefaultHandler method works fine.

Though I haven’t carefully checked your code, at first glance you don’t need to override Read & Write

Hi @gankeyu,
I seem to have solved it. Turns out just having a placeholder in the ClearCaches methods is a problem.
After defining that one properly it seems to be working now. Thank you for you help :slight_smile:

1 Like