Changing a CRhinoLight

I’m trying to add some markup to a CRhinoLight using SetUserString(), however I can only get a const CRhinoLight pointer meaning its read-only.

How do you make changes to a CRhinoObject? I can cast away the const, but thats not going to tell Rhino the object has changed.

I’m not sure about lights specifically, but usually you follow a pattern like this:

const CRhinoLight* light;// obtained somehow

CRhinoLight newLight(*light); // make a copy using copy-constructor

newLight.SetUserString(L"hello world\n"); // set user string

context.m_doc.ReplaceObject(light, newLight); // replace object

context.m_doc.RedrawViews(); // redraw the scene (if necessary)

Oo, nice. OK, will give it a whirl.

Thanks very much menno - really had me stumped!


Looks like the ctor for lights in private

Maybe there is a DuplicateLight() function, that can be used instead of copy ctor?
Again, I’m not familiar with CRhinoLight class, but a Duplicate<> function seems to be a common pattern.

I can SetUserString() on a CRhinoLight and it can be read back just fine. Its simply if the Document is saved and reloaded, the string is no longer there.

The headers claim that the UserStrings will survive any I/O operation but for Lights I am not seeing this.

Is this known to work? Has any developers added UserStrings to CRhinoObjects successfully?

Here is a sample you will find useful.

Lights are an odd object because all manipulation happens thru the light table (CRhinoDoc::m_light_table) even though you can find the objects in the object table.

– Dale

Hi Dale,

Thanks. I have followed this example, but when I try and apply the same code to the SelectedObjects, it does not work.

I have made it work by just setting it on Light Attributes, but its really not clear why it does not work for Light that are from the selection.

And today I tried the same Attributes() technique on CRhinoMaterials and find that does not appear to be supported…

I just want a way of setting some state on Rhino objects! What is the preferred way for Lights, Meshes and Materials?


Hi Adam,

Did you try the sample code - it works with either pre or post-selected objects.

Like I said, lights are special object and, thus, need to be treated differently than normal geometric objects. The sample code demonstrates this. Of course, attaching user text to object attributes is just fine too.

CRhinoMaterial is not derived from CRhinoObject. Thus, they do not have attributes.

User text is the easiest way to store extra data on anything. The sample demonstrates how to do this with stuff you can pick. For materials, just make a copy of the material, add your user text, and then modify the material by calling CRhinoMaterialTable::ModifyMaterial. There is a material table on the document.

– Dale

Thank Dale,

I’m in Helsinki all week, so I’ll try it out when I get back to the UK.

So I draw from this, that the tables in Rhino are the Primary Objects, with CRhinoObjects being proxies created to give uniformity? I had been viewing the tables as a convenience maintained by Rhino.

ie I should look to decorate table objects such as ON_Light and ON_Material with User strings, not the CRhinoObjects.

[ It goes without saying I’ve run the SampleUserText sample, and it worked for the GO objects, but didn’t work for GetSelectedObjects(). ]


I have no idea what this means. But, basically, you add user strings to any object derived from ON_Object.

Again, I have no idea what this means - sorry.