Get various blocks in c#

Hi,

how to get several blocks in c# in GH? I tried the code without for loop and I can get the Block, changing it to get a List brings up the error.In english: error: The object reference was not set to an object instance. (line: 75)
Both blocks are in the rhino file.

Thanks for every hint!

Regards!

files:
gh:blockTest.gh (4.3 KB)
rhino: blockTest.3dm (23.8 KB)

You need to change the access of iBlock to List

Hi @gankeyu,

thank you for taking time.
In the screenshot it wasnt put to List, but in the file it was.
So it seems not to be the reason. Maybe you have another idea?

  1. “Multline data” needs to be checked for the panel.
  2. GeometryBase gb = objects[i].DuplicateGeometry(); should be GeometryBase gb = objects[0].DuplicateGeometry();
  3. Assign gbs to A

Yes! Thanks a lot, that works perfect!

Can you share what you did in the end to make it work? I just tried, but still getting the same error.

var gbs = new List<GeometryBase>();

for (int i = 0; i < iBlock.Count; i++)
{
  InstanceDefinition def = RhinoDocument.InstanceDefinitions.Find(iBlock[i]);
  RhinoObject[] objects = def.GetObjects();
  GeometryBase gb = objects[0].DuplicateGeometry();
  gbs.Add(gb);
  gbs = (List<GeometryBase>) A;
}

Is that what you did?

blockTest_v2.gh (3.5 KB)

Looks like your def variable is null, meaning it did not find a block during an iteration. You should check for null before you do anything with your def variable.

Hi Armin,
this should work:

 var gbs = new List<GeometryBase>();

    for (int i = 0; i < iBlock.Count; i++)
    {
      InstanceDefinition def = RhinoDocument.InstanceDefinitions.Find(iBlock[i]);
      RhinoObject[] objects = def.GetObjects();
      GeometryBase gb = objects[0].DuplicateGeometry();
      gbs.Add(gb);

    }
    A = gbs;

In general your error message appears if you dont have an input(as @rawitscher-torres mentioned)

Regards

Thanks, you are right, that DOES work now. Oh of course I missed that the output is still inside the loop.

Now I just need to get ALL the objects in the Block, not just the first one. How would I do that (sorry, I don’t know much about C#). Another loop inside it to not just get objects[0], but all of them. Or probably there is a much easier way.

ps: ideally it would output it everything in branches :wink: so one branch with all the geometry for each block

I think that would be the way to go:

 var geoTree = new DataTree<GeometryBase>();
    for (int i = 0; i < iBlock.Count; i++)
    {
      InstanceDefinition def = RhinoDocument.InstanceDefinitions.Find(iBlock[i]);
      RhinoObject[] objects = def.GetObjects();
      for (int j = 0; j < objects.Length; j++)
      {
        GeometryBase gb = objects[j].DuplicateGeometry();
        geoTree.Add(gb, new GH_Path(i));
      }  
    }
    A =geoTree;
1 Like

Thanks, that seems to work perfectly!

Sorry, little further question. We have blocks that contain blocks also. Is there a way to explode the inside of the block first so that it handles that and doesn’t expect just to find geometry inside the block?

Hi Armin,

I am sorry,I tried today but I could’t find a solution.
Maybe there is a way to do it with Elefront?
Or one of the c# pros here can help out.

Elefront has options in the block reference components for Levels and Deconstruction.