Convert different layers to materials



been working with Keyshot for years and for that it requires all same materials on same layer before export.
(assign material by layer) Now working with Lumion and it requires same materials setup as objects (assign material by object) before export into lumion.

so to convert my old models I have been selecting all objects in a layer and then assigning them to a material.
and so on…

is there an easy way to convert each seperate layer to an individual material object?

sorry if niot too clear, not easy to explain!

(Lando Schumpich) #2

I’m not totally sure I understood. You need every object to have a different, unique material?

If it’s hard to explain in words you can always just post a file that shows what you have now and what you need to have later as a valid setup for lumion export


for lumion each object with the same material, i.e metal chrome, needs to have a unique material assigned.

For keyshot each object with same material needs to be assigned to the same layer.

(Lando Schumpich) #4

Would a different name for the material be enough? For example create copies of the layer material “metal_chrome” for each object on it and name them “metal_chrome_001”, “metal_chrome_002”, etc

(Pascal Golay) #5

So… assign each object on a layer the material that the layer has… ?



yes correct


here is a movie to show what I am doing…

I have been working with keyshot - this requires all the same material to be on same layer.

Now I am testing lumion and it requires all same material to be assigned via object…

is there an easy way to convert my rhino model?

(Lando Schumpich) #8

From the link you posted:

" * If you assign the material to a layer, all objects on the layer will then be identified by that material name when imported in Lumion "

Anyways here is a script that creates one new, uniquely named material per layer and then assigns this material to all objects on this layer

import Rhino
import scriptcontext as sc

def assignNewMaterialByLayer():
    # disable redraw, because depending on the number of objects this could get heavy
    sc.doc.Views.RedrawEnabled = False
    # create a dict to keep track of material <-> layer relation
    layerMaterialDict = {}
    # iterate over all layers in the doc
    for layer in sc.doc.Layers:
        # create a new material
        newMaterial = Rhino.DocObjects.Material()
        # name it like the layer fullpath, because fullpath is ALWAYS unique
        newMaterial.Name = layer.FullPath
        # add it to the doc, so we can assign it to objects
        index = sc.doc.Materials.Add(newMaterial)
        # finally store in the dict together with its layer
        layerMaterialDict[layer.Index] = index
    # iterate over all objects
    for object in sc.doc.Objects:
        # assign a material by layerindex, easy to do with our dict
        object.Attributes.MaterialIndex = layerMaterialDict[object.Attributes.LayerIndex]
        # tell the object to use its assigned material as its materialsource
        object.Attributes.MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromObject
        # commit the changes we made
    # re-enable redraw
    sc.doc.Views.RedrawEnabled = True
    # and redraw all views so we can see what we did
if __name__ == "__main__":


Hello Lando
that works great, many thanks… I did not expect someone to create code, I thought there might be a standard way to do this in rhino…

The Lumion documention is mis leading! your script works just how I want it to work.

many thanks