I have bought an obj model of a car, just to painfully discover that all meshes are on the same layer with about 30 different materials applied to them, hence my question:
Should it be possible by script (I can do some python) to select an object, take its material name, create a layer with that name and move the object to that layer?
This works here on separate meshes with standard rhino materials. No error proofing so could be dangerous. I’d open the obj in separate rhino file, run script, then copy it into your real file. If the entire car mesh is joined then it won’t work as it needs separate doc objects to change layer attribute. Also, if the materials are 3rd party render content, I’m not sure it will work.
Works like a CHARM!
Tried it on vray materials and the onlz concern is that it keeps the “/” that the plugin/rhino adds before the material name, but that’s no worrz. Either I delete it bz hand or even better I trz to tweak your code with my little python skills to have it done automatically.
Hi! I have been thinking that it is a really useful script! Also I was thinking if that’s for example possible to do same on Rhino Blocks? To make it open each one and assign the layers to material names accordingly? That would 100% solve most of my issues with models from different workflows.
creates layer based on object name, moves respective object to this layer.
in Rhino “EditPythonSCript”, paste code an run. Takes all available objects withoun prior manual selection.
# -*- coding: utf-8 -*-
import rhinoscriptsyntax as rs
def main():
# get objects
objs = rs.AllObjects()
if not objs:
print("no objects found ?!")
return
for obj in objs:
# get obj name
obj_name = rs.ObjectName(obj)
if not obj_name:
print("Object has no name, discarded:", obj)
continue
# if layer does not exist yet, create layer
if not rs.IsLayer(obj_name):
rs.AddLayer(obj_name)
print("Create Layer:", obj_name)
# move object to layer
rs.ObjectLayer(obj, obj_name)
print("if you like to move it, move it", obj, "in Layer", obj_name)
if __name__ == "__main__":
main()
Script lets user create sublayers for further seperation: assign new sublayer name and select according objects, cycle through all layers. Prompt “stop” to cancel ooperation.
# -*- coding: utf-8 -*-
import rhinoscriptsyntax as rs
import scriptcontext as sc
def isolate_layer(layer_name):
"""Blendet alle Layer auĂźer 'layer_name' ein."""
all_layers = rs.LayerNames()
if not all_layers:
return
for lay in all_layers:
rs.LayerVisible(lay, lay == layer_name)
def restore_all_layers():
"""Schaltet alle Layer wieder ein."""
all_layers = rs.LayerNames()
if not all_layers:
return
for lay in all_layers:
rs.LayerVisible(lay, True)
def main():
# Hole alle vorhandenen Layer
layers = rs.LayerNames()
if not layers:
rs.MessageBox("Keine Layer vorhanden.", 0, "Fehler")
return
for main_layer in layers:
objs = rs.ObjectsByLayer(main_layer)
if not objs:
continue # Ăśberspringe leere Layer
# Isoliere den aktuellen Hauptlayer
isolate_layer(main_layer)
rs.Redraw()
print("Bearbeite Hauptlayer:", main_layer)
while True:
# Abfrage des Zusatznamens fĂĽr einen neuen Sublayer.
# Hinweis: Mit ESC kann das gesamte Script abgebrochen werden.
prompt = "Gib einen Zusatznamen fĂĽr einen Sublayer von '{}' ein (oder 'stop' zum Beenden)".format(main_layer)
user_input = rs.StringBox(prompt)
if user_input is None:
# ESC gedrĂĽckt => Script abbrechen
print("Script wurde abgebrochen.")
restore_all_layers()
return
# Falls "stop" eingegeben wird, beende die Bearbeitung des aktuellen Layers.
if user_input.strip().lower() == "stop":
print("Beende Bearbeitung von Layer:", main_layer)
break
new_sublayer = "{}_{}".format(main_layer, user_input.strip())
if not rs.IsLayer(new_sublayer):
rs.AddLayer(new_sublayer)
print("Neuer Sublayer erstellt:", new_sublayer)
else:
print("Sublayer '{}' existiert bereits.".format(new_sublayer))
# Nutzer wählt nun die Objekte (Teilmeshes) aus, die in den neuen Sublayer verschoben werden sollen.
sel_objs = rs.GetObjects("Wähle Objekte für Sublayer '{}' aus (ESC zum Abbrechen)".format(new_sublayer), preselect=True)
if sel_objs is None:
# ESC gedrückt während der Objektauswahl => komplettes Abbrechen des Scripts
print("Script wurde abgebrochen während der Objektauswahl.")
restore_all_layers()
return
# Verschiebe die ausgewählten Objekte in den neuen Sublayer
for obj in sel_objs:
rs.ObjectLayer(obj, new_sublayer)
print("Objekt {} in Sublayer {} verschoben.".format(obj, new_sublayer))
rs.Redraw()
# Nachdem alle Sublayer fĂĽr den aktuellen Hauptlayer angelegt wurden, werden alle Layer wieder eingeblendet.
restore_all_layers()
rs.Redraw()
print("Sublayer-Erstellung abgeschlossen.")
if __name__ == "__main__":
main()