Exploding a block gives document controlled objects

Hi all,

within a plugin I was trying to explode linked block to use its components.
It all works fine with single standard blocks. But nested linked problems causes some problems.

As an example:
file A and file B are inserted in file C as linked blocks.
When using C as linked block in file D and exploding this block the result is obviously having linked blocks A and B in D. Unfortunately there is always ONE of these resulting blocks that is document controlled and can not be moved, deleted or edited in whatever way. It stays there where it is. Only by closing and opening the file this block will gone…

Code snippet (within a command):

ObjRef objRef = RS.RNGet.GetObject("get block", ObjectType.InstanceReference);
            ObjRef[] objRefs;
            Rhino.Input.Custom.GetObject go;
            go = new Rhino.Input.Custom.GetObject();
            go.SetCommandPrompt("get instance object");
            go.GeometryFilter = ObjectType.InstanceReference;
            go.SubObjectSelect = false;
            go.AcceptNothing(true);
            //go.GetMultiple(1,0);


            go.Get();
            if (go.CommandResult() != Rhino.Commands.Result.Success)
                return Result.Cancel;

            objRef = go.Object(0);
            if (objRef == null)
            {
                return Result.Cancel;
            }

            InstanceObject instObj = objRef.Object() as InstanceObject ;
            if(instObj==null)
            {
                return Result.Cancel;
            }


            RhinoObject[] explodedObjects;
            ObjectAttributes[] attributesOfExplodedObjects;
            Transform[] transformOfExplodedObjects;

            instObj.Explode(false, out explodedObjects, out attributesOfExplodedObjects, out transformOfExplodedObjects);

            Guid[] IDs = new Guid[explodedObjects.Length];
            for (int i = 0; i < explodedObjects.Length; i++)
            {
                Guid addedObjectID;
                if (explodedObjects[i].ObjectType != ObjectType.InstanceReference)
                {
                    addedObjectID = doc.Objects.Add(explodedObjects[i].Geometry, explodedObjects[i].Attributes);
                }

                else
                {
                    addedObjectID = doc.Objects.AddInstanceObject(((InstanceObject)explodedObjects[i]).InstanceDefinition.Index, ((InstanceObject)explodedObjects[i]).InstanceXform);
                }
                var addedObject = doc.Objects.Find(addedObjectID);


                addedObject.Geometry.Transform(transformOfExplodedObjects[i]);
                addedObject.CommitChanges();
                IDs[i] = addedObjectID;
            }

            doc.Views.Redraw();

            return Result.Success;

I can provide the files as well…

Corrected code (forgot to delete some lines, sorry):

ObjRef objRef;
            Rhino.Input.Custom.GetObject go;
            go = new Rhino.Input.Custom.GetObject();
            go.SetCommandPrompt("get instance object");
            go.GeometryFilter = ObjectType.InstanceReference;
            go.SubObjectSelect = false;
            go.AcceptNothing(true);
            //go.GetMultiple(1,0);


            go.Get();
            if (go.CommandResult() != Rhino.Commands.Result.Success)
                return Result.Cancel;

            objRef = go.Object(0);
            if (objRef == null)
            {
                return Result.Cancel;
            }

            InstanceObject instObj = objRef.Object() as InstanceObject ;
            if(instObj==null)
            {
                return Result.Cancel;
            }


            RhinoObject[] explodedObjects;
            ObjectAttributes[] attributesOfExplodedObjects;
            Transform[] transformOfExplodedObjects;

            instObj.Explode(false, out explodedObjects, out attributesOfExplodedObjects, out transformOfExplodedObjects);

            Guid[] IDs = new Guid[explodedObjects.Length];
            for (int i = 0; i < explodedObjects.Length; i++)
            {
                Guid addedObjectID;
                if (explodedObjects[i].ObjectType != ObjectType.InstanceReference)
                {
                    addedObjectID = doc.Objects.Add(explodedObjects[i].Geometry, explodedObjects[i].Attributes);
                }

                else
                {
                    addedObjectID = doc.Objects.AddInstanceObject(((InstanceObject)explodedObjects[i]).InstanceDefinition.Index, ((InstanceObject)explodedObjects[i]).InstanceXform);
                }
                var addedObject = doc.Objects.Find(addedObjectID);


                addedObject.Geometry.Transform(transformOfExplodedObjects[i]);
                addedObject.CommitChanges();
                IDs[i] = addedObjectID;
            }

            doc.Views.Redraw();

            return Result.Success;

Hi @DominikIC,

Can you post your 3dm files?

Thanks,

– Dale

Sure, here are the files…A.3dm (21.3 KB)
B.3dm (22.7 KB)
C.3dm (30.0 KB)
D.3dm (27.9 KB)

Hi @DominikIC,

There is quite a bit of work in exploding linked block instances. For example, all of the object attributes must be remapped to properties (e.g. layers, etc.) in the active document (since you cannot write to the linked document).

For now, I can only recommend scripting the Explode command, as there isn’t enough exposed in RhinoCommon to do what you need.

I’ve created a YouTrack issue to address this in a Rhino service release.

https://mcneel.myjetbrains.com/youtrack/issue/RH-48919

– Dale

Hi Dale,

alright, thanks for the help.
So I will use the explode command for now and wait for future Releases on that :slight_smile:
Dominik