Serialization issue

I have a plugin that suddenly fails on serialization, specifically it states that Rhino.Collections.Point3dList + XAccess is not marked as serializable. I am fairly certain this issue just appeared, but also am confused, as I can’t find anywhere in my code where I use that class. I do have a few references to Point3dList but they are old, nothing changed there. I also and using Plankton very recently, but I am marking those fields to not serialize (which corrected that error).

Hi @wes_mcgee_3d,

Why are you using a Point3dList collection and not a List<Point3d>?

– Dale

TBH,
I am not really using them, I searched my (massive) plugin for any references and a few methods popped up somewhere, in unrelated code. The references that popped up shouldn’t actually be being serialized. Just to make sure I am not mistaken, if I browse in VS to the class Rhino.Collections.Point3dList, and right click find all references, this should show me anytime I use that class, correct? When I do the same on Rhino.Collections.Point3dList.XAccess it tells me no references found, but when I save my file I get an exception in my serialization method. I assume this means that class is being called internally inside a rhino class which I reference, which I then serialize?

I checked the Plankton source and I don’t see any refs to this either. I would be happy to make it a List but I don’t know how to find it :slight_smile: . It wasn’t me!

Edit: I just looked, the reason I used that collection was I was calling its .Transform() method to move all the points in one go. But I just refactored it out to be sure.

Edit2: I found it. In a class I just added, I serialized a Polyline. This inherits Point3dList, which includes child classes XAcess etc…Amazing that I never tried to serialize a polyline (and odd that it is such a big deal to try). I can factor this out, I don’t really need to store it.

1 Like

Good investigatoin @wes_mcgee_3d as I’m having the same error and never used any Point3dLists … But I do need to store the polyline. Any ideas how can I do that elegantly?

I would override the ISerializable interface. In the OnSerialize event, convert the Polyline to an array. Convert back in the OnDeSerialize event. I do this for several types, its not too hard to implement.

That’s a good idea. I tried implementing it but unfortunately arrays or lists of points don’t get deserialized properly. If I deserialize a single Point3d it works but otherwise I get the correct number of points in the list/array but all with 0,0,0 coordinates. I’m sure I’m doing something wrong but don’t know where… Here is my deserialize constructor:

   public SkeletonData(SerializationInfo info, StreamingContext context)
   {
            List<List<Point3d>> clPts = new List<List<Point3d>>();
            List<List<List<Point3d>>> egPts = new List<List<List<Point3d>>>();

            // Reset the property value using the GetValue method.
            Active = (int)info.GetValue("active", typeof(int));
            clPts = (List<List<Point3d>>)info.GetValue("centreLines", typeof(List<List<Point3d>>));
            Density = (int)info.GetValue("dens", typeof(int));
            DominantAxis = (int)info.GetValue("domAxis", typeof(int));
            egPts = (List<List<List<Point3d>>>)info.GetValue("edges", typeof(List<List<List<Point3d>>>));
...skipped code here
    }

I use this to duplicated objects in memory and create a Deep copy of classes that is independent on changes in the class members.

Edit: For some reason Point3d does not serialize if in arrays or list. I fixed the issue by converting all lists to PolylineCurve class which serializes well. But then I noticed the extreme performance hit that I was not seeing if I do the copy member by member. I guess this cannot be fixed as far as I see so the fastest copy is just to assign all properties and data respectively.

Yeah maybe I was thinking of a simpler approach, but yours may be faster. My classes are all already serialized by default, and I normally don’t mess with this by defining the serialization ctor. Lots of properties get marked as non-serialized though, as they will be recomputed on de-serialization. I was simply thinking that you create two methods

    [OnSerializing]
    internal void OnSerializingMethod(StreamingContext context)
    {
    }

    [OnDeserializing]
    internal void OnDeserializingMethod(StreamingContext context)
    {
    }

In the first, you convert your polyline to a list of points (as a property or field of the class). Note that you polyline should be marked as NonSerialized. Then in the second method, you convert it back. I agree that a polylineCurve will add overhead.

1 Like