Import and layer renaming

I’m writing a python script to import a file and set imported layers to a new parent layer. In order to avoid imported objects from being inserted on an existing layers, the process is to temporarily rename existing layers, import, move new layers to new parent layer, and the revert the temp name.

This works great but undoing does not revert the original layers back to the original layer names, as pointed out in this thread: https://discourse.mcneel.com/t/problems-with-multiple-layer-naming-in-one-command/38502/2

Is there a better way to work around this bug? I think another method might be to move all imported objects that get put into existing layers back onto new layers, but that seems overly complicated, especially if blocks are involved. Thoughts?

Hi Kyle

What would be complicated about moving the imported to new layers?
How about this workflow:
You collect all object ids before import. After import you get the imported by comparing the current set of all objects to it.
Next for each new object id, get the layer, create the new layer if it does not exist and move it on the new layer.

Or am I missing some issue?

-Willem

Thanks for the feedback.

That’s what I ended up doing. I was worried this might be intensive if there were a lot of objects, as the script would have to iterate through them all just to see if it was on the right layer, where a simple changing and changing back of the layer name I assume would be faster. But in the end it seems to work just fine.

The only downside i see to this is that any differences in layer attributes from the imported layer are lost if the layer exists in the current document. For example, say I have layer “Default” with a red color in my import file and a layer “Default” with a black color in my open file, the objects would be moved to current “Default” layer. when I iterate through to create a new layer for that object, the script has no way of knowing that layer was red before.

Hopefully that makes some sense. As of now, the bare bones concept works fine.

Hi Kyle,

What you can do is to load the imported file through Rhino.FileIO
This way you can lookup the layer attributes of the the imported layers and apply them to the new layers

I made a quick proof of concept.
in the zip 2 files and the script: layer_importer.zip (27.5 KB)

import rhinoscriptsyntax as rs
import Rhino
import os


def import_colored_layers():
    
    """
    import document colored_layers.3dm
    from some folder as current doc
    """
    
    
    old_ids = set( rs.AllObjects() )
    
    import_filepath = os.path.join(rs.DocumentPath(), 'colored_layers.3dm')
    rs.Command('_-Import "{}" _Enter'.format(import_filepath))
    
    new_ids = set( rs.AllObjects() )
    
    #get imported objects by difference between sets
    imported_ids = new_ids - old_ids
    
    # next we load the document with Rhino.FileIo
    # that allows us to find the layer attributes of the imported file
    # we could have doen this anyway and imported the objects through here but that is a lot of work
    # letting the import command take care of that is easier
    
    # we import only the layer table as that is all we need
    import_file = Rhino.FileIO.File3dm.Read(import_filepath)
    import_layers = import_file.Layers # layer table from the imported file
    
    
    #construct dictionary to quickly get the imported layer object based on layername
    layer_dict = {}
    for layer in import_layers.GetEnumerator():
       layer_dict[str(layer)] = layer
    
    
    for id in imported_ids:
        id_layer = rs.ObjectLayer(id)
        import_layer = layer_dict[id_layer]
        
        #make new layername for imported
        new_layername = 'IMPORTED::{}'.format(id_layer)
        #create the new layer if not present
        if not rs.IsLayer(new_layername):
            rs.AddLayer(new_layername)
            #get the color from the layer in the imported file
            rs.LayerColor(new_layername, import_layer.Color)
            
            
        rs.ObjectLayer(id, new_layername)
    
    
    
    
    
    
import_colored_layers()

Does this make sense?
-Willem

2 Likes

Ah yes that is very helpful!

Thank you