Grasshopper unrecognized objects problem

Okay, here’s my first stab at the problem - it appears to work fine for the Addition component and simply throws an error if there are more than 2 inputs :slight_smile:

(Hopefully the name should discourage anyone from reckless use on critical files)
experimental_grasshopper_surgery.gh (7.4 KB)
test_subject.gh (6.6 KB)

Before:


After:

I don’t have access to a Rhino 6, so I haven’t tested this with the Multiplication and Subtraction components yet, but it should be a matter of obtaining their GUIDs and putting them into the mapping dictionary.

Also it’s my first time using GH_IO, so there are some bits that might not be done correctly like changing the name of a GH_Chunk by messing with its read-only field m_name

import os
import clr
clr.AddReferenceByName("GH_IO")
import GH_IO
from GH_IO.Serialization import *
from GH_IO.Types import *
from System import Guid
from System.Reflection import BindingFlags
from System.IO import BinaryReader, BinaryWriter, MemoryStream, SeekOrigin
import rhinoscriptsyntax as rs


new2old_mapping = {
    Guid("a0d62394-a118-422d-abb3-6af115c75b25"): Guid("d18db32b-7099-4eea-85c4-8ba675ee8ec3"),  # addition
    "???": Guid("2c56ab33-c7cc-4129-886c-d5856b714010"),  # subtraction
    "???": Guid("b8963bb1-aa57-476e-a20e-ed6cf635a49c")  # multiplication
}
param_name_map = {"InputParam": "param_input",
                  "OutputParam": "param_output"}

# read only attributes:
chunk_name_field = clr.GetClrType(GH_Chunk).GetField("m_name", BindingFlags.NonPublic | BindingFlags.Instance)  # type: FieldInfo
# print "\n".join(map(str, clr.GetClrType(GH_Chunk).GetMembers(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)))


def main(file_name):

    archive = GH_Archive()
    archive.ReadFromFile(file_name)

    root = archive.GetRootNode  # type: GH_Chunk
    defn = root.FindChunk("Definition")
    objs = defn.FindChunk("DefinitionObjects")

    for obj in objs.Chunks:
        obj_guid = obj.GetGuid("GUID")  # type: GH_Item

        if obj_guid in new2old_mapping:
            print "Found new ZUI component \"{}\"".format(obj.FindItem("Name"))

            container = obj.FindChunk("Container")
            if not container.FindChunk("ParameterData"):
                continue
            if container.FindChunk("ParameterData").GetInt32("InputCount") != 2:
                msg = "ZUI component \"{}\" has more than 2 inputs,\ncannot convert to older component".format(obj.FindItem("Name"))
                print msg
                rs.MessageBox(title="Surgery Error",
                              message=msg,
                              buttons=0)  # OK button only
                continue
                # alternatively Abort => break, don't write archive, Ignore => continue

            # replace the guids
            repl_guid = new2old_mapping[obj_guid]
            print "Replacing GUID {} with {}".format(obj_guid, repl_guid)
            obj.RemoveItem("GUID")
            # obj.Items.Add(GH_Item("GUID", new2old_mapping[obj_guid])) # doesn't work
            obj.SetGuid("GUID", repl_guid)

            for param_chunk in container.FindChunk("ParameterData").Chunks:

                chunkname = param_chunk.Name
                new_chunk = container.CreateChunk(chunk_name=param_name_map[chunkname],
                                                  chunk_index=param_chunk.Index)
                ms = MemoryStream()
                writer = BinaryWriter(ms)
                reader = BinaryReader(ms)

                param_chunk.Write(writer)
                ms.Seek(0, SeekOrigin.Begin)
                new_chunk.Read(reader)  # this overwrites the chunk.Name value, so it has to be written again
                # setting a "read only" field (!!)
                chunk_name_field.SetValue(new_chunk, param_name_map[chunkname])

            print "removing ZUI params: ", container.RemoveChunk(container.FindChunk("ParameterData"))

    archive.WriteToFile(file_name.replace(".gh", "_edited.gh"), True, True)


if button:
    main(file_name)

Are any other parametric modelers forward or backward compatible. My (limited) experience with solidworks is that there is no compatibility at all between versions because slight tweaks of components/features can have significant effects on the model, which isn’t a good scenario.