script_load

Create a new temporary script. Load an existing Python file into the Script Manager. Retrieve the first script not active in the Script Manager and make it active.

script_load.py

"""Create a new temporary script. Load an existing Python file into the Script Manager. Retrieve the first script not active in the Script Manager and make it active.

Topics:
    * c4d.CreateNewPythonScript()
    * c4d.LoadPythonScript()
    * c4d.GetScriptHead()
    * c4d.GetDynamicScriptID()
    * c4d.SetActiveScriptObject()
"""
__author__ = "Maxime Adam"
__copyright__ = "Copyright (C) 2026 MAXON Computer GmbH"
__license__ = "Apache-2.0 License"
__version__ = "R26"

import c4d
import os


def CreateNewPythonScript():
    """ Create a new temporary script.
    """
    # Create a new temporary script. The first argument is the script name. If an empty string is used as the script
    # name, Cinema 4D will generate automatically the name. The second argument being the content of the script.
    # The new script will be set as active automatically.
    newScript = c4d.CreateNewPythonScript("", r"print('Sometimes science is more art than science.')")

    # Due to the type ScriptObject being derived from BaseList2D, the bracket operator syntax can be used to access
    # the parameters of an instance.
    scriptName = newScript[c4d.PYTHONSCRIPT_SCRIPTNAME]

    # An empty PYTHONSCRIPT_SCRIPTPATH indicates that this script has not been
    # saved and will be deleted once Cinema 4D closes.
    scriptPath = newScript[c4d.PYTHONSCRIPT_SCRIPTPATH]

    # PYTHONSCRIPT_TEXT returns the Python script visible in the Script Manager.
    scriptContent = newScript[c4d.PYTHONSCRIPT_TEXT]

    print(f"Added '{scriptName}', its content in the Script Manager is:\n{scriptContent}")


def LoadExistingPythonScript():
    """Load an existing Python file into the Script Manager.
    """
    scriptPathToLoad = os.path.join(os.path.dirname(__file__), "reg_plugin_info.py")

    # Load the script into the Script Manger and set it automatically as the active script.
    loadedScript = c4d.LoadPythonScript(scriptPathToLoad)

    # Due to the type ScriptObject being derived from BaseList2D, the bracket operator syntax can be used to access
    # the parameters of an instance.
    scriptName = loadedScript[c4d.PYTHONSCRIPT_SCRIPTNAME]

    # An empty PYTHONSCRIPT_SCRIPTPATH indicates that this script has not been
    # saved and will be deleted once Cinema 4D closes.
    scriptPath = loadedScript[c4d.PYTHONSCRIPT_SCRIPTPATH]

    # PYTHONSCRIPT_TEXT returns the Python script visible in the Script Manager.
    scriptContent = loadedScript[c4d.PYTHONSCRIPT_TEXT]

    print(f"Load '{scriptName}', from '{scriptPath}' it's content in the Script Manager is:\n{scriptContent}")


def SetActiveScript():
    """Retrieve the first non-active script in the Script Manager and set it as the active script.

    Scripts visible in the Script Manager are represented by BaseList2D instances stored under a GeListHead.
    """
    def HierarchyIterator(obj):
        """Yields nodes from a GeListNode tree.
        Args:
            obj: The starting object of the python generator (will be the first result)
        Returns:
            All objects under and next of the `obj`
        """
        while obj:
            yield obj
            for opChild in HierarchyIterator(obj.GetDown()):
                yield opChild
            obj = obj.GetNext()

    # Retrieve the script list head.
    scriptHead = c4d.GetScriptHead()

    # Retrieve the first non-active script in the Script Manager and set it as the active script.
    # A script is active when it has its code displayed in the Script Manager.
    for scriptOp in HierarchyIterator(scriptHead.GetFirst()):
        # Go to the next script object if the script is already active in the Script Manager.
        if scriptOp.GetBit(c4d.BIT_ACTIVE):
            continue

        # Retrieve the unique plugin ID generated by Cinema 4D for this script.
        scriptId = c4d.GetDynamicScriptID(scriptOp)

        # Set the script with the ID #scriptID as the new active script
        c4d.SetActiveScriptObject(scriptId)

        # Due to the type ScriptObject being derived from BaseList2D, the bracket operator syntax can be used to access
        # the parameters of an instance.
        scriptName = scriptOp[c4d.PYTHONSCRIPT_SCRIPTNAME]

        # An empty PYTHONSCRIPT_SCRIPTPATH indicates that this script has not been
        # saved and will be deleted once Cinema 4D closes.
        scriptPath = scriptOp[c4d.PYTHONSCRIPT_SCRIPTPATH]

        # PYTHONSCRIPT_TEXT returns the Python script visible in the Script Manager.
        scriptContent = scriptOp[c4d.PYTHONSCRIPT_TEXT]

        print(f"Set as active '{scriptName}', saved in `{scriptPath}` with the next content in"
              f" the Script Manager is:\n{scriptContent}")

        break


def main():
    CreateNewPythonScript()
    LoadExistingPythonScript()
    SetActiveScript()


if __name__ == "__main__":
    main()