Change layer of object?

Hi All,

I’ve hit a wall on what should be a simple problem. I’m creating a polyline from a list of points, and I want to assign it to a layer (specified by a string). the function executes without error, but it doesn’t make the change in the document (by inspection).

What am I doing wrong?

def InsertPolyLine(doc, Points: list, Layer: str):

    ob = doc.Objects
    rg = Rhino.Geometry

    for i in range(len(Points)):
        Points[i] = rg.Point3d(Points[i][0], Points[i][1], 0.0)

    poly = rg.Polyline()
    for p in Points:
        poly.Add(p)

    if poly.IsValid:
        poly = doc.Objects.Find(ob.AddPolyline(poly))
        poly.Attributes.LayerIndex = doc.Layers.FindName(Layer).Index
    
    doc.Views.Redraw()
    return poly

Thanks in Advance.

Do you just need to create the layer first, then assign it to the object?

https://developer.rhino3d.com/api/RhinoScriptSyntax/#layer-AddLayer

Is this in Rhino via Python or in Grasshopper? Does the layer already exist?

This is via Rhino python. The layer already exists in the document template.

Apologies for the vague post… It’s been a long day…

import Rhino
from Rhino import Geometry as rg
import scriptcontext as sc
import rhinoscriptsyntax as rs

def TestInsertPL(pts,layer_name):
    poly=rg.Polyline(pts)
    if poly.IsValid:
        layer_index=sc.doc.Layers.FindByFullPath(layer_name,False)
        if layer_index and layer_index != -1:
            attrs=Rhino.DocObjects.ObjectAttributes()
            attrs.LayerIndex=layer_index
            obj_id=sc.doc.Objects.AddPolyline(poly,attrs)
            sc.doc.Views.Redraw()
            return obj_id
        else:
            print("Layer does not exist")
    
pts=rs.GetPoints("Pick points")
if pts: 
    result=TestInsertPL(pts,"PointsLayer")
    if not result: print("Unable to comply")
1 Like

Thanks for that. This solution assigns the layer (and other attributes) at the time of creation, which is good enough for my application, but how would you go about changing the layer of an existing polyline?

In my case, I expected to create the polyline, then change it. I’m happy with your solution, but still curious about changing an existing polyline.

Well, once the polyline has been written to the Rhino document, it has an ID - you can then use the rhinoscriptsyntax method rs.ObjectLayer() to change the object layer:

#add the layer if it doesn't already exist
if not rs.IsLayer(new_layer): rs.AddLayer(new_layer)
#change the object layer
rs.ObjectLayer(obj,new_layer)

If you want to stay in RhinoCommon:

import Rhino
from Rhino import Geometry as rg
import scriptcontext as sc
import rhinoscriptsyntax as rs

def TestInsertPL(pts,layer_name):
    poly=rg.Polyline(pts)
    if poly.IsValid:
        layer_index=sc.doc.Layers.FindByFullPath(layer_name,False)
        if layer_index and layer_index != -1:
            #add the polyline to the document and return the ID
            obj_id=sc.doc.Objects.AddPolyline(poly)
            #get the object reference from the ID
            rhobj=sc.doc.Objects.Find(obj_id)
            #change the layer index
            rhobj.Attributes.LayerIndex=layer_index
            rhobj.CommitChanges()
            sc.doc.Views.Redraw()
            return obj_id
        else:
            print("Layer does not exist")
    
pts=rs.GetPoints("Pick points")
if pts: 
    result=TestInsertPL(pts,"PointsLayer")
    if not result: print("Unable to comply")

In general, once you are dealing with objects in the document with GUID’s, it’s just much easier to use rhinoscriptsyntax.

2 Likes

Thanks for that. So far, I’ve been avoiding rhinoscriptsyntax (just to avoid too many flavours of python), but this is a solid argument for its inclusion.