Unable to change light object attributes

In RhinoCommon, I’m trying to modify the attributes of a light, but it’s not working as expected. Changes to the LightObject attributes don’t seem to stick to the document.

With regular objects, I usually delete and re-add them and it works fine. But with lights, re-adding gives the light a new ID every time, probably because the original light is still “in use” even after being deleted. This is a problem because I need to keep track of the same light using its ID.

Another issue: when looping through the Lights table, I often get null objects, so it’s hard to know what’s actually in there, especially if something was deleted. And unlike other tables, there doesn’t seem to be a way to purge lights properly.

Also, when working with File3dm, I can’t access the light table at all, which blocks any attempt to import lights into the current document.

Would love to know if there’s a workaround, or if this could maybe be improved in RhinoCommon in the future. Thanks!

Here is a simple script to change the color of lights randomly:

// #! csharp
using System.Drawing;
using System;
using System.Collections.Generic;
using Rhino;

var rng = new System.Random();

int min_c = 75;
int max_c = 245;

// Dictionary to record changes we want to make
Dictionary<Guid, Rhino.Geometry.Light> lights = new Dictionary<Guid, Rhino.Geometry.Light>();

// Record new light geometry in a dictionary, shouldn't modify
// a table in a loop you're reading in.
foreach(var l in __rhino_doc__.Lights) {
    Rhino.Geometry.Light lg = l.DuplicateLightGeometry();
    lg.Diffuse = System.Drawing.Color.FromArgb(
        255,
        rng.Next(min_c, max_c),
        rng.Next(min_c, max_c),
        rng.Next(min_c, max_c));
    lights[l.Id] = lg;
}

// Now modify the light changes we recorded
foreach(KeyValuePair<Guid, Rhino.Geometry.Light> kvp in lights) {
    __rhino_doc__.Lights.Modify(kvp.Key, kvp.Value);
}

Ah no, maybe it was not clear what I mean with Attributes, I mean the ObjectAttributes.

LightObject existing = doc.Lights.FindId(id.Id);

then

existing.Attributes = restore.Attributes.Duplicate();

or

existing.Attributes.LayerIndex = restore.Attributes.Duplicate().LayerIndex;

Doesn’t seem to do anything.

I’m not sure how to do that with our current API. @maxsoder do you have any idea how to update light object attributes?

1 Like

Another thing to log maybe as a request is if the lights table can iterate LightObjects and also be able to access the lights table from file3dm, is not possible at the moment

I might have understood this wrong, but do you mean the light geometry like intensity and so on?

Is there a

existing.LightGeometry.Intensity

Edit

I see I misunderstood the question. I do not know how the object attributes work for lights.

I have logged RH-87445 Unable to replace LightObject ObjectAttributes

1 Like

Would it be possible to log also:

–Request to access lights table in fil3dm
–Lights table iteration returns null elements and not LightObject

Logged

  1. RH-87476 Add light table access through File3dm
  2. RH-87477 Issues iterating lights table

Try this:

LightObject existing = doc.Lights.FindId(id.Id);
var attr = existing.Attributes.Duplicate();
attr.LayerIndex = myLayertIndexValue;
existing.Attributes = attr;
existing.CommitChanges();

I believe that works.

Some of the issues iterating the oight table are as-designed. Lights aren’t really the same as other tables because they are RhinoObjects in the document. They are generally kept in the table and marked deleted, in part because they may be marked not deleted in the event of an undo.

I am not sure what might cause an entry to become null, though. Do you have an example?

Hi Bill, I will try committing the changes.

Here is what I mean with the nulls, either existing or deleted lights are there as null, not as LightObject


OK, that’s strange. In my tests so far they are all there and the deleted ones are marked

IsDeleted == true

Do you have something you could send me that reproduces the null behavior? What platform are you working on?

This works in Rhino 8:

#! python 3
import Rhino
import scriptcontext as sc

def test():
    obj_type = Rhino.DocObjects.ObjectType.Light
    rc, objref = Rhino.Input.RhinoGet.GetOneObject("Select light", False, obj_type)
    if not objref or rc != Rhino.Commands.Result.Success:
        return

    light_obj = objref.Object()
    if isinstance(light_obj, Rhino.DocObjects.LightObject):
        if 0 != light_obj.Attributes.LayerIndex:
            attributes = light_obj.Attributes.Duplicate()
            attributes.LayerIndex = 0
            sc.doc.Objects.ModifyAttributes(objref, attributes, False)
            sc.doc.Views.Redraw()

if __name__ == "__main__":      
    test()

– Dale

This is on Rhino Windows using Rhino 8 latest build.

I just create some lights and then loop them in a command, nothing special.

RH-87445 is fixed in Rhino 8 Service Release 21 Release Candidate