Block instance counts WITHOUT opening a file

Hello,

We’re trying to find a way to get block counts (nested and top level) similar to what you see on the BlockManager in V8, without opening a .3dm file.

I have tried using Rhino.Inside Python and the rhino3dm library, but neither seem to have access to the RhinoCommon UseCount() method.

InstanceDefinition.UseCount method

So I’ve been left with a solution that is doing recursion and incrementally counting instances based on what doc.Objects is returning. Is there a better/smarter/faster approach?

Thanks,

Dan

ps - @Japhy I hope all is well with you!

Hi lignindes,

How about loadding the files with https://developer.rhino3d.com/api/rhinocommon/rhino.fileio.file3dm.
And do some bookkeeping through the ObjectTable:

# coding=utf-8
from __future__ import division

import rhinoscriptsyntax as rs
import Rhino


def report_instance_definitions_in_3dm(file_path):


    model = Rhino.FileIO.File3dm().Read(file_path)
    if model is None:
        rs.MessageBox('Could not read file:\n{0}'.format(path))
        return

    instances  = []
    all_parents = []
    objects = model.Objects
    for object in objects:
        if object.Geometry.ObjectType == Rhino.DocObjects.ObjectType.InstanceReference:
            instances.append(object)
            all_parents.append(object.Geometry.ParentIdefId)
    
    blocks = model.InstanceDefinitions
    
    for block in blocks:
        print '{} times {}'.format(all_parents.count(block.Id), block.Name)


    pass

if __name__ == '__main__':
    
    """Browse for a .3dm, load via File3dm.Read, report block defs and insert counts."""
    file_path = rs.OpenFileName(
        'Select a Rhino .3dm file',
        'Rhino 3DM (*.3dm)|*.3dm||'
    )
    if file_path:
        report_instance_definitions_in_3dm(file_path)

You can load it with filters ( I assume to lower read time / resources)

https://developer.rhino3d.com/api/rhinocommon/rhino.fileio.file3dm.objecttypefilter

https://developer.rhino3d.com/api/rhinocommon/rhino.fileio.file3dm.tabletypefilter

Does that help?

@Willem

Yes, this does help. I’ve learned something new by reading through and testing your script. It works! But shows that you’re still using RH7 (no brackets around the print statement) - it took me a long time to switch over to RH8.

My overarching challenge is to try and ‘harvest’ data from several Rhino files in a folder, then take the data and aggregate it somewhere else - ideally so that it can be shared among the broader team. I want to have quick ‘point in time’ health checks to monitor a project over time. This is root of my desire to not have to open the Rhino file, or even execute the script/software within Rhino.

I’m clearly still working through rough concepts, but would appreciate hearing if there are any other users out there who have tried to accomplish something similar.

Thanks,

Dan

Hi @lignindes

Indeed this was a quick mockup in RH7

I suspect that with the rhino3dm library this would be possible as a standalone Cpython script.
The prerequisite is that from a 3dm file you can find for each object the object.Geometry.ParentIdefId
and that the InstanceDefinitions table contains the block definitions and their Id to match to the objects.

I expect both to be possible so there is no need to run this through a Rhino instance.

Or am I missing something?