Worksesison Update Wipes off Materials on Enscape for Rhino


I’ve been doing some investing regarding this very well-known issue with Enscape on Rhino as outlined on the forum below.

Worksessions updating loses materials

Enscape seems to be completely clueless about this issue, so I decided to look into issues on technical levels.

First, I suspected Object ID & Material ID, and as it turned out they are static and can’t be altered on worksession. After a bit of trying and error, I’ve noticed that Material Index do get renumbered everytime worksesion gets updated. So, could this be a case of loss of the materials on enscape?

So some questions here, does anyone know what Rhino or Enscape use Material Index for? And, would it be possible to force Rhino to not-renumber them?

I may well be all wrong about this. But it would be great if anyone could shine some light on this issue and hopefully help enscape to resolve this long outstanding issue…

Here are before and after screenshots showing the little code I sued and how Material Index are renumbered after worksession update.

Thanks very much in advance!

1 Like

+1 to this. It baffles me how oblivious the Enscape team is to it despite all the forum posts.

1 Like

As of July 2nd, Enscape is saying it is a McNeel issue. Is that true? Is a fix in the works?

I personally am not aware of a bug logged about this with us. That said, the best way to get the correct materials from objects regardless of where they originate from is to use the .RenderMaterial property on a RhinoObject instance.

from Rhino.Render import RenderTexture as rt
import scriptcontext as sc

for ob in sc.doc.Objects:
    render_material = ob.RenderMaterial # get a RenderMaterial
    oldskool_material = render_material.SimulatedMaterial(rt.TextureGeneration .Allow) # from the RenderMaterial get the Material

Not sure why anybody in this day and age would want to use the old-school Material. We’re trying to move people to use the RenderMaterial approach instead.

I’ve got the same response back in July too…

Thank you for an interesting thought, but this method doesn’t seem to be able to get the materials from the objects that are on worksession though; or am I missing sth?

Ah, right. I kinda forgot about the fact this is about worksessions. Could you replicate the OP from the Enscape forum here? I have no login there, so can’t read it.

I don’t know much about the worksession part of our scripting API, I’m asking around how one is supposed to handle those.

That said, on the very first question in your first post: the material index a material or object (ob.Attributes.MaterialIndex) is an index into the old-school materials table. This table works in a peculiar way as that after adding a material to an otherwise empty document doesn’t show in that Materials table. Entries show up only once a material is assigned. Say you add after the material two boxes to the model. Now assign your material to one box. You’ll find that the Materials table now contains one entry. Assign your material also to the other box. You’ll find that the Materials table now contains two entries. A material will have as many entries in the Materials table as it is being used: objects, layers, etc. Indices change on model updates, and I guess that is what is happening here too on activating another attached model.

Anyway, this is all very cumbersome with the old method that includes handling everything yourself, including using the Materials table.

For rendering solutions we’ve introduced the ChangeQueue mechanism in Rhino 6. This unifies a lot of work that render engines each otherwise would have to do themselves: meshing objects, handle block instance hierarchies, worksessions, and so on.

That is why I don’t have to worry about worksessions and all that, because Raytraced and Rhino Render (both running the Cycles render engine) are implemented using the ChangeQueue mechanism. This handles all the intricacies of worksessions, block instances and so on for the renderer. I automatically get all the RenderMaterials for all objects even after another attached model has been made active. I don’t have to match and rematch material indices from the old-school materials. Instead I get to use all the modern, good bits of the Rhino RDK.

Wow I didn’t realize Enscape now made the forum member-only, it wasn’t previously…
anyway, here you go.

Thank you for the detailed explanations! It sounds like Enscape somehow hasn’t fully implemented ChangeQueue mechanism then, despite them supporting only Rhino 6 & 7…

I guess they’re still using the old method of doing everything themselves. I don’t know how they are doing it. But perhaps they are not rereading the new indices from the materials table?

I just tested updating an attached model while having Raytraced running, and that works just fine. New geometry have the materials showing as expected.

1 Like

Ya, that sounds like the most plausible reason…

Anyway thank your reply and hope Enscape will fix this soon…!

Ok, after some asking around you can do something like this to iterate over all objects, including referenced objects from worksession attached models:

from Rhino.Render import RenderTexture as rt
import scriptcontext as sc
import Rhino
import Rhino.DocObjects

obenum = Rhino.DocObjects.ObjectEnumeratorSettings()

obenum.ReferenceObjects = True

for ob in sc.doc.Objects.GetObjectList(obenum):
    print ob
    render_material = ob.RenderMaterial # get a RenderMaterial
    if render_material:
        oldskool_material = render_material.SimulatedMaterial(rt.TextureGeneration.Allow) # from the RenderMaterial get the Material
        print render_material, render_material.Name, oldskool_material

This way there is no need for knowing material indices and to try fiddle around with matching them up and so on.

1 Like

Hi Natan,

Thanks for the solution.
I don’t have knowledge about coding.
Could you explain where and how i can use the code?

I appreciate your help in advance.

Hi , I only show how to access the modern material API for objects that are references (brought in from worksessions). This in itself does not fix the problem of Enscape not managing the materials correctly - that is up to Enscape devs to fix on their side.

Thank you for showing an interest in this forum.

Unfortunately, this is a solution not for us but for Enscape to fix the issue. This solution is also based on a series of the assumptions we made so it may not be right, but only Enscape knows…

if anything it would be great if you could write to escape about this forum discussion, and that may help to resolve the issue once and for all…

Hi Tomohiro,

I wrote my inquiry to Enscape.

Thanks for your reply.