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.
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?
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.
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.
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()
I’m trying to do something similar to this, so I tried borrowing the scripting, but no dice, as I’m new to scripting. Starting to understand, but still a bit slow
GOAL: I’d like to import an external 3dm with a template Layer set, that I can use each time I’m building a new element in my current work file (see image)
I’d have the script:
Ask for NewLayerName
Import the empty ElementLayerSet
ReplaceLayerName where XXX = NewLayerName
Down the road I might have it ask for a selected object, and if it has a name, use it as NewLayerName. Plus, automatically file it in the suitable sublayer dependent on the object type (i.e. crv, srf/sol, etc.) or material (obj with emissive mat wld get filed in “Light”) I’ve been collecting snippets that I know will be needed for doing these types of things, so it woll be a good way to practice my scripting…