How to exclude nested blocks inside externally linked blocks

The script below manages to exclude nested blocks that are inside embedded blocks, but doesn’t seem to work for blocks nested inside externally linked blocks (those inserted with “Linked” “Reference” options).

What could work is testing if > is in the name, but I think that on Apple operating system files can have > in the name, so I would warmly welcome another solution for testing if blocks are nested inside linked blocks.

import rhinoscriptsyntax as rs

block_names = rs.BlockNames()

# rs.BlockContainerCount excludes nested blocks inside blocks embedded 
# into current Rhinodoc, but doesn't work for externally linked blocks
block_names_not_nested = [block_name for block_name in block_names 
                            if rs.BlockContainerCount(block_name) == 0]

# select them
selected_blocks = rs.MultiListBox(sorted(block_names_not_nested))
for selected_block in selected_blocks:
    block_instances = rs.BlockInstances(selected_block)
    rs.SelectObjects(block_instances)

Hi @Daniel_Krajnik,

Can you clarify what problem you are trying to sollve? I’m not sure I’m following you conversation.

Thanks,

– Dale

Sorry, what I meant is that rs.BlockNames() lists all blocks in the document, including blocks inside blocks. What would help me is a method to call only the “top-most” blocks (excluding blocks inside blocks). The method I found was checking if rs.BlockContainerCount was equal to 0, but this only worked for embedded blocks. Nested blocks inside blocks linked to a file were not filtered out.

Hi @Daniel_Krajnik,

So if I understand correctly, if you had a model that had this:

─ Instance definition 0 (Block 01)
  └ Object 0 (curve)
─ Instance definition 1 (Block 02)
  └ Object 0 (instance reference: Block 01)
  └ Object 1 (curve)

You only want Block 01 returned?

– Dale

1 Like

Yes, that’s correct. Hoping that would behave the same regardless what UpdateType these blocks have (e.g. Static, Embeddded, Embedded and Linked or Linked).

Hi @Daniel_Krajnik,

How about this?

import Rhino
import scriptcontext as sc

def test():
    clean_idefs = []
    for idef in sc.doc.InstanceDefinitions:
        found = next((obj for obj in idef.GetObjects() if isinstance(obj, Rhino.DocObjects.InstanceObject)), None)
        if not found:
            clean_idefs.append(idef)
    for idef in clean_idefs:
        print(idef.Name)

if __name__ == "__main__":        
    test()

– Dale

1 Like

That’s brilliant, thank you! I haven’t thought of this GetObjects() method. That totally solves it :grinning: