Adding a block from another file

Hi everyone!

I have a rhino file with hundreds of possible facade parts each of them modelled as a Block. Let’s call it a facade library. My goal is to import only certain blocks from the facade library to my current file according to the facade type defined by the user. Thus I can make the file size manageble and keep the library up-to-date without the need of manually importing blocks every time something is changed.

To this point I managed to collect all the InstanceDefinitions from the library file using Rhino.FileIO.File3dm.Read() and AllInstanceDefinitions property. But I can’t find a way to import an InstanceDefinition from a libary into my active RhinoDoc. Is there anything i’m missing?

I found an old thread with a similar question How to import selected blocks from a File3dm? (Or were blocks saved incorrectly in this file?) with an example from @dale but the file is not available anymore.

Max

i dont know if its doable via grasshopper but see elefront plugin for GH. there are some nodes for importing linked blocks etc

you can do this via elefront plugin if thats an option for you.

1 Like

Thanks for suggestion but it’s a little trade-off since all the blocks have to be kept in separate files. It’s interesting though how these components are done. I suppose it uses -insert command internally, I’ll give it a try anyway.

Ok. I made it finally
Here is a code sample in case anyone needs it.

private void RunScript(string filePath, string blockName)
{

    int index = -1; //instance definition index

    //check if block exists in current file;
    var localDef = RhinoDocument.InstanceDefinitions.Find(blockName);

    if (localDef != null)
    {
      index = localDef.Index;
    }
    else //get block from the outer file
    {
      var refDoc = Rhino.FileIO.File3dm.Read(filePath);

      var instDefs = refDoc.AllInstanceDefinitions;

      //find the blocks needed
      var instDef = instDefs.Where(d => d.Name == blockName).FirstOrDefault();

      if (instDef != null)
      {
        //add layers to current document otherwise imported blocks will loose layers/color
        var refLayers = refDoc.AllLayers;
        foreach (var layer in refLayers)
        {
          RhinoDocument.Layers.Add(layer);
        }

        //find block Objects
        var refObjects = refDoc.Objects;
        var ids = instDef.GetObjectIds();
        var objs = ids.Select(id => refObjects.FindId(id));

        //Add Instance Definition to the current file
        index = RhinoDocument.InstanceDefinitions.Add(blockName, string.Empty, Point3d.Origin, objs.Select(o => o.Geometry), objs.Select(o => o.Attributes));
      }
    }

    //Place new block to the document
    var xform = Transform.Identity;
    RhinoDocument.Objects.AddInstanceObject(index, xform);

}

3 Likes

Can anyone please tell me where in GH interface i should put this (above post) code to make it work?

If you just need to place an external block you can use Elefront plugin

If you need some more control over the process you need to place the code in c# component and refine it there. See the attached example.

place block from external file.gh (3.5 KB)

i was little bit dissapointed that elefront handles linked blocks in fashion that the whole linked document is a “block” and does not actually insert blocks from that document. I suppose your script works in that way. I am going to try thanks :slight_smile:

It seems to work except there is an issue with layers.
Source file with block “1” is originally put on layer “block”


Insides of the block is places on layer “lala”

After placement in other document using the script layers are somehow messed. Block is placed on “default” layer instead on block layer and insides are placed on mysterious “layer 01” instead “lala” .layer 01 had not existed in the source file nor current file.

There is probably some small error in the script. I took a look at it but i cant help myself :smiley:

I believe if you keep the same layer structure in block file and in your main file everything should work fine. It might not be always possible though.

I’ll try to import needed layers from the block file later today

Thank you for the favor. I believe it is just small adjusment to the script.

The point is i am creating larger script which strongly depends on the ability to load blocks from other files retaining all the attributes.

I need same behaviour via GH just like if i copy paste a block from other file (which brings its layers etc with it).

Actually i dont even need to place the component in the model space, only block defined (visible only in blockmanager) is preffered.

Moment I get my blocks from other files loaded (defined in blockmanager) i will then use elefront to insert the block by name from my current file.

I found an old code I used for importing facade blocks from the ‘library’ file. It doesn’t import block attributes but it does import all the layers from the file with blocks.

Try it out

import blocks from external file.gh (5.3 KB)

Moment I get my blocks from other files loaded (defined in blockmanager) i will then use elefront to insert the block by name from my current file.

This can be tricky. It might require to “recompute” solution in order to work properly.

Best,
Max

This one seems to work but it omits lot of data regarding blocks. It does not bring material used in the block etc. It works reliably just for geometry.

I see only viable way how to achieve what i need is to manually import files containing blocks from Rhino interface. Then delete everything in the model space and rest can be done with elefront insert block component.

I find it bit disappointing though it is not possible to control Rhino from GH straight forwardly with Rhino commands. All would be much easier. This particular operation (insert block from other file) can be done inside rhino with ctrl c ctrl v just copying and pasting block from other file but to achieve the same thing you would need hundred line code in GH.

Nevermind. Thank you for this anyways.

Actually i found a post of your regarding automated printing from GH i tried it with PDF creator it seems to work somewhat but when generating pdfs for more branches all pdfs seem to be the same no matter separation in data provided into script. Do you still use it?