GH/VBScript - Replace Block Definition while keeping Instances?

Q: Is it possible to keep Block Instances while updating (replacing) the Block Definition, and then re-reference the Instances back to the (updated/replaced) Block Definition again?

In the code snippet below I’d like to pick up the instances, replace the definition, and re-reference the (existing) Instances, if any, back to the replaced Block Definition :

Current GH/VBScript does not allow delete while there are instances, so I would need to “disconnect” the instances before delete. But is such a trick possible, or do I have to re-create any existing Block Instances from scratch?

Dim Block_tmp As Rhino.DocObjects.InstanceDefinition 

'//BLOCK DEF EXIST?
block_tmp = rh.InstanceDefinitions.Find(BlockName, True) 
If Block_tmp IsNot Nothing Then
    '// REPLACE EXISTING BLOCK DEF (?)
    rh.InstanceDefinitions.Delete(Block_tmp.Index, False, False) '//False=Keep references, False=Not Quiet
End If

// Rolf

Hi Rolf,

I don’t believe this is possible.

But what you can do is get the transform from the existing InstanceObject. Then after you’ve defined the new instance definition, insert an instance of it and used the transform.

– Dale

I’m not sure I understood that sentence.

Did you mean “insert an instance of it and use the transform” or “insert an instance of it using the transform”?

I also do not fully grasp what a “transform” is in this context. From the only documentation I found on it, it looks like a function rather than a class or object, but…

I once used a “Transform.Identity” in my code , but I didn’t really know what it was, and whatever it was, it was taken right “out of nowhere” (see code snippet below), so that leaves me with the question of how to get the “Transform” out of an existing Instance? Can you provide a link to relevant documentation, or a code snippet ? :

    '//CREATE INSTANCE
    If Instantiate Then
      Dim ObjId As Guid = doc.Objects.AddInstanceObject(NewDef, Transform.Identity)
      '//SET NAME
      Dim Obj As RhinoObject = rh.Objects.Find(ObjId)
      If Obj IsNot Nothing Then
        Obj.Attributes.Name = Trim(InstanceName)
        Obj.CommitChanges()
        Log([String].Format("19 BLOCK INSTANCE NAME ('{0}') was added.", Obj.Name))
      Else
        Log([String].Format("20 ADDING BLOCK INSTANCE ('{0}') FAILED!", InstanceName))
      End If
      doc.Views.Redraw()
    End If

// Rolf

Dale meant get the transform from an existing instance, and then create a new instance pointing to a different block definition with the same transform.

A ‘transform’ is 4x4 transformation matrix, which encodes all manner of different transformations. It can describe translations (move), rotations, reflections, dilations (scale) and even shearing and tapering. A block instance is little more than a pointer to a block definition and an associated transform. Thus if you want to replace one block with another, what you need to do is copy the transform of the old instance, delete the old instance, and insert a new instance which points to a different definition but using the old transform.

1 Like

OK, thanks David, that was a very clear description. Although the general principle of a instance references was clear to me (reminds about classes and objects), the transform part wasn’t self evident. But your very clear explanation will be of great value and I can now dig deeper into Rhino’s exposed functionality.

// Rolf