Setting Layer.Id

Hi messing up with baking layers assigning a custom Id…

I found that sometimes (!?) I’m not able to change a freshly baked layer Id because its Layer.IdIsLocked state is set to True.

I particular: I don’t understand what needs to happen for a layer to be set as IdIsLocked=True

already hours spent trying to figure out a pattern for this behavior. Some doc layers are blocked, others no ?!

In the end, what I just want to do is to bake a layer which ID is set by me, but “IdIsLocked” is blocking my attempts…

by the way, this is on WIP…

why this doesn’t work? once baked the layer.id is changing??

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
import Rhino.Geometry as rg
import System

doc = Rhino.RhinoDoc.ActiveDoc
newGuid = System.Guid.NewGuid()
print newGuid
layer = Rhino.DocObjects.Layer()
layer.Id = newGuid
layer.Name = 'TestName01'
layerIndex = doc.Layers.Add(layer)
layer = doc.Layers[layerIndex]
print layer.Id

Instead, if i bake a layer, get it from table, Delete() it from layerTable, set new Id and finally bake again, I end up with a baked layer with an ID choosen by me.

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
import Rhino.Geometry as rg
import System

doc = Rhino.RhinoDoc.ActiveDoc
layer = doc.Layers.FindName('test',True)
print 'found layer name: {0}'.format(layer.Id)
print layer.IdIsLocked

doc.Layers.Delete(layer)
layer.Id=System.Guid.NewGuid()
layer.Name = 'test'
print 'new layer id: {0}'.format(layer.Id)
print layer.IdIsLocked

index = doc.Layers.Add(layer)
layer = doc.Layers[index]
print 'new layer id: {0}'.format(layer.Id)
print layer.IdIsLocked


Is this behavior new in WIP? A would say that I have done this much easier in the past, as I did in my previous post

Edit: Well… baking, deleting, setting, rebaking is not much work, but figuring it out get me hours… Is this the only way to bake a layer with a prefixed ID??

Hi @aitorleceta,

See if this make sense:

import System
import Rhino
import scriptcontext as sc

def dump_layer(layer):
    if layer:
        print 'Name: {0}'.format(layer.Name)
        print 'Index: {0}'.format(layer.Index)
        print 'ID: {0}'.format(layer.Id)
        print 'ID Locked: {0}'.format(layer.IdIsLocked)

def test_layer_id(name):
    
    # Try finding the layer in the document
    index = sc.doc.Layers.FindByFullPath(name, Rhino.RhinoMath.UnsetIntIndex)
    if index == Rhino.RhinoMath.UnsetIntIndex: return
    layer = sc.doc.Layers[index]
    if not layer: return
    
    # dump
    dump_layer(layer)
    
    # Cannot delete current layer
    if index == sc.doc.Layers.CurrentLayerIndex: return
    
    # Delete layer
    sc.doc.Layers.Delete(layer)
    
    # Since the document layer has been deleted, our reference it
    # no longer valid. So, set it to None so we don't try to use it.
    layer = None

    # Create a new layer and set its properties
    new_layer = Rhino.DocObjects.Layer()
    new_layer.Name = name
    new_layer.Id = System.Guid.NewGuid()

    # dump
    dump_layer(new_layer)
    
    # Add the new layer to the document
    index = sc.doc.Layers.Add(new_layer)
    
    # Get the layer from the document
    layer = sc.doc.Layers[index]

    # dump
    dump_layer(layer)

# Test the above
test_layer_id('test')

– Dale

Thank Dale, please read my comment inserted in your code:

import System
import Rhino
import scriptcontext as sc

def dump_layer(layer):
    if layer:
        print 'Name: {0}'.format(layer.Name)
        print 'Index: {0}'.format(layer.Index)
        print 'ID: {0}'.format(layer.Id)
        print 'ID Locked: {0}'.format(layer.IdIsLocked)

def test_layer_id(name):
    
    # Try finding the layer in the document
    index = sc.doc.Layers.FindByFullPath(name, Rhino.RhinoMath.UnsetIntIndex)
    if index == Rhino.RhinoMath.UnsetIntIndex: return
    layer = sc.doc.Layers[index]
    if not layer: return
    
    # dump
    dump_layer(layer)
    
    # Cannot delete current layer
    if index == sc.doc.Layers.CurrentLayerIndex: return
    
    # Delete layer
    sc.doc.Layers.Delete(layer)
    
    # Since the document layer has been deleted, our reference it
    # no longer valid. So, set it to None so we don't try to use it.
    layer = None

    # Create a new layer and set its properties
    new_layer = Rhino.DocObjects.Layer()
    new_layer.Name = name
                                         # AITOR'S COMMENT
    new_layer.Id = System.Guid.NewGuid() # AITOR'S COMMENT: What I need is to set the old Layers id
                                         # AITOR'S COMMENT: Not a new random one. Is this possible? 

    # dump
    dump_layer(new_layer)
    
    # Add the new layer to the document
    index = sc.doc.Layers.Add(new_layer)
    
    # Get the layer from the document
    layer = sc.doc.Layers[index]

    # dump
    dump_layer(layer)

# Test the above
test_layer_id('test')

Thank Dale. I finally discovered the piece of info that I was missing: The id of the layers that are present in the layer table (including the deleted layers) is not possible to be reused with other layer. This was not obvious in the case of deleted layers… The only way (afaik) to use that ID is using the Undelete() method of layerTable class, supposing that the layerId we want to use belong to a deleted layer. (otherwise layer+layerId would were already present in the document)

phiu, this has taken a couple of days, but finally working!