Rhino 3D Tip: Batch Rename and Colorize Layers with Rhino.Python

November 17, 2025 2 min read

Rhino 3D Tip: Batch Rename and Colorize Layers with Rhino.Python

Rhino.Python lets you build lightweight tools that remove repetitive clicks and enforce your team’s standards. Here’s how to start quickly and a practical script you can adopt today.

  • Open the editor: type EditPythonScript to launch the Rhino Python editor.
  • Use the high-level API: rhinoscriptsyntax (import as rs) for fast, readable tools.
  • When you need deeper control, call RhinoCommon via Python for full access to geometry and doc settings.
  • Save scripts to a shared folder and bind them to aliases or toolbar buttons for one‑click use.

Sample tool: batch rename and colorize layers with persistent options (great for project standards). Paste into the editor, save, and run.

import rhinoscriptsyntax as rs
import scriptcontext as sc
import System.Drawing as sd

def main():
    layers = rs.LayerNames() or []
    if not layers:
        rs.MessageBox("No layers in this document.", 48, "Rhino.Python")
        return

    # Sticky options persist between runs
    prefix = rs.GetString("Prefix (Enter for none)", sc.sticky.get("rpy_prefix", "PRJ_"))
    if prefix is None: return
    suffix = rs.GetString("Suffix (Enter for none)", sc.sticky.get("rpy_suffix", ""))
    if suffix is None: return

    colorize = rs.GetBoolean(
        "Apply colors to layers?",
        ("Colorize", "No", "Yes"),
        sc.sticky.get("rpy_colorize", True)
    )
    if colorize is None: return

    purge = rs.GetBoolean(
        "Purge empty layers after rename?",
        ("Purge", "No", "Yes"),
        sc.sticky.get("rpy_purge", True)
    )
    if purge is None: return

    sc.sticky["rpy_prefix"] = prefix
    sc.sticky["rpy_suffix"] = suffix
    sc.sticky["rpy_colorize"] = colorize[0]
    sc.sticky["rpy_purge"] = purge[0]

    palette = [
        sd.Color.FromArgb(230,57,70),
        sd.Color.FromArgb(29,53,87),
        sd.Color.FromArgb(69,123,157),
        sd.Color.FromArgb(42,157,143),
        sd.Color.FromArgb(233,196,106),
        sd.Color.FromArgb(244,162,97),
        sd.Color.FromArgb(231,111,81),
        sd.Color.FromArgb(168,218,220),
    ]

    renamed = 0
    i = 0
    for old in layers:
        if not rs.IsLayer(old): 
            continue
        base = old.split("::")[-1]  # keep leaf names tidy
        newname = "{}{}{}".format(prefix or "", base, suffix or "")

        target = newname
        if rs.IsLayer(target) and rs.LayerId(target) != rs.LayerId(old):
            k = 1
            while rs.IsLayer(target):
                target = "{}_{}".format(newname, k)
                k += 1

        if target != old:
            rs.RenameLayer(old, target)
            renamed += 1

        if colorize[0]:
            rs.LayerColor(target, palette[i % len(palette)])
        i += 1

    if purge[0]:
        for lname in (rs.LayerNames() or []):
            objs = rs.ObjectsByLayer(lname, select=False)
            if not objs:
                try: rs.DeleteLayer(lname)
                except: pass

    rs.StatusBarMessage("{} layers processed.".format(renamed))

if __name__ == "__main__":
    main()
  • Create a one-click alias:
    • Windows/Mac: Options > Aliases > New
    • Command macro: !-_RunPythonScript "C:\Tools\rename_layers.py"
  • Speed tips:
    • Use scriptcontext.sticky to remember user preferences.
    • Wrap heavy operations with rs.EnableRedraw(False/True) to accelerate.
    • For commands without an API, call Rhino commands with options via rs.Command().
    • Respect document tolerances: read via sc.doc.ModelAbsoluteTolerance for consistent results.

Need Rhino licenses, upgrades, or expert advice? Visit NOVEDGE at novedge.com and explore Rhino solutions at NOVEDGE | Rhinoceros. Their team can help you standardize your scripting workflow across your studio.



You can find all the Rhino products on the NOVEDGE web site at this page.







Also in Design News

Subscribe