Add Block Instance into file

Good afternoon sirs!

I’m currently experimenting on how I can exchange information from rhino to python and the other way arround. So I was testing how to write a block instance into a 3dm file.
Here is what I coded so far:

    success, block = check_block_in_file3dm(True, block_name, rhino_file3dm)
    rhino_layer = Rhino.DocObjects.Layer()
    rhino_layer.Name = 'objects'
    rhino_layer.Color = System.Drawing.Color.FromArgb(0, 227, 144)
    rhino_object_attributes = Rhino.DocObjects.ObjectAttributes()
    rhino_object_attributes.LayerIndex = rhino_layer.Index
    rhino_object_attributes.Name = block_name
    xform = rg.Transform()
    xform.M03 = 1
    xform.M13 = 1
    xform.M23 = 0
    file3dm.Objects.AddInstanceObject(block.Index, xform, rhino_object_attributes)
    file3dm.Write("test_exports/test-export-to-rhino.3dm", 6)

Where check_block_in_file3dm(True, block_name, rhino_file3dm) is:

def check_block_in_file3dm(prev_success: bool, block_name: str, file3dm):
    success = False
    block = None
    all_blocks = file3dm.AllInstanceDefinitions
    for b in all_blocks:
        if b.Name == block_name:
            success = True
            block = b
    return(success, block)

The ‘block’ variable used is a valid InstanceDefinitionGeometry and the code runs without erros, but the 3dm file created has no objects in it. Any ideia on where the problem is?
I guess that I still don’t understand how to add InstanceObjects into a document.

Thank you.

Hi @thomas.takeuchi,

Do you really need to write an instance definition to a 3dm file? Doing so will cause Rhino to created a nested block upon insertion.

– Dale

Hello @dale, thank you for the reply!

The idea was to have a central file, template, with all needed blocks, like so:

And then, when needed, place one of those blocks into a new, empty, file.
Would there be another way to achieve the same intented objective?


Imo a better way would be to store every block as a single file and just insert each file as you need it. You can script the insert command or do it with rhino common.

Hello rgr,

Thank you for replying. Could you give me an example on how I could do that?
Is there an Insert Method in Rhino Common?


Maybe have a look at this thread:

Basicly what you are doing is a) using the RhinoScript Method
oe b) see the link @jeffoulet just posted.

Thank you very much @rgr @jeffoulet!
I’ll definitely try that!


Hello guys, I just now realised that I never gave you a followup to my issue.
Taking your advices, I manage to acomplish what I wanted, wich was to load all blocks from a reference file3dm into a target file3dm.
I’m sure that this will be helpful to someone in the future so here is how I did it:

def explode_block(
file3dm_objects: File3dmObjectTable,
block: InstanceDefinitionGeometry,
) -> IEnumerable:
    Explode a block into its composing elements
            A reference file3dm containing the block to be exploded
            A block to explode

            An Enumerable list of composing elements from exploded block

        block_elements = List[Rhino.Geometry.GeometryBase]()
        for obj_id in block.GetObjectIds():
            if obj_id is not None:
                obj = file3dm_objects.FindId(obj_id).Geometry

        return IEnumerable(block_elements)

def load_all_blocks_from_file3dm(
file3dm_src: File3dm,
file3dm_tgt: File3dm,
) -> File3dm:
        Load all blocks form a source File3dm into a target File3dm
            A source file3dm containing all blocks to be loaded
            A target file3dm where the blocks will be loaded

            A modified file3dm with all blocsk loaded from reference file

        For now, it only works with block that are not composed out of
        other blocks
        For that purpose it is necessary to add recurssion to function


        all_blocks_src = file3dm_src.AllInstanceDefinitions
        all_objects_src = file3dm_src.Objects

        for block in all_blocks_src:

        return file3dm_tgt
1 Like