Freelance Plugin Developer
Only passing True, False and c4d.CMD_ENABLED|c4d.CMD_VALUE will effect the icon state correct? it can't be done outside of the state() function?
Yes. You may be able to perform calculations elsewhere and store a state value in the document's container that you access in the state() method, but I don't believe you can change the state elsewhere.
I noticed when I put a print function inside of the state() function it seemed to loop endlessly? if I use this code:
Yes, it's "looping" every time the Cinema 4D interface updates/redraws.
The state() function is seemingly run every time Cinema 4D's interface is redrawn. It's really there for determining whether a command that requires an object be selected is enabled or not. As it's run so frequently, any code you put in there could slow down all of C4D, so ensure that your state check is actually important, and if so, do your check as quickly as possible.
For example, a script that prints the name of the selected object should only be enabled when an object is selected.
"""Name-en-US: Echo Name
Description-en-US: Opens a message dialog with the name of the selected object.
from c4d import gui
"""Gray out icon if no objects are selected, or more than one object is selected.
# `op` is a variable provided by C4D that represents the selected object.
# I'm not certain, but I think this is faster than call doc.GetActiveObject()
# but it will return `False` if more than one object is selected.
if op is not None:
"""Open a dialog with the selected object's name.
if op is None:
active_obj_name = op.GetName()
gui.MessageDialog("You selected: " + active_obj_name)
Has anyone had any luck getting R21's c4dpy.exe to work with the current release of VS Code? I've followed the installation instructions but I'm consistently prompted to "Select Python Interpreter", even though I've set "python.pythonPath": "C:/Program Files/Maxon Cinema 4D R21/c4dpy.exe" in the VS Code application and workspace settings.
"python.pythonPath": "C:/Program Files/Maxon Cinema 4D R21/c4dpy.exe"
I've been able to get it running in PyCharm, but VS Code doesn't seem to recognize c4dpy.exe as a valid python interpreter.
Any suggestions or insights would be greatly appreciated.
Realizing I never responded to this Thank you @m_magalhaes, @mikegold10, and @PluginStudent.
I ended up manually making a list of the parameters I wanted to copy and iterating through all of them. Not ideal, but at least glad to know there wasn't an automated method I was missing.
Not the answer I was hoping for, but helpful nonetheless! Thank you.
Gotcha. So, at least for now, we can't develop tools/commands for manipulating nodes in the "active" node editor. Thanks for the thorough response! The GetSceneNodesGraph method is really useful, might be worth adding it into the API as a convenience function. Same for a GetActiveMaterialNodeGraph() or something similar for materials.
I'm looking to create some node alignment scripts (Align Vertical, Align Horizontal), and to do that, I believe I'll need the following information:
Which (if any) of the above methods currently exist?
I'll edit this post if my own research turns up anything useful.
Realizing there are even more considerations:
Now that I'm realizing you can have multiple open Node Editors, some w/ locking, some without, I can imagine this being a similar challenge to the "Which timeline is active?" problem.
How to Get the Selected Keyframes in Active Timeline/FCurve Manager | PluginCafé
Get Active Timeline Request | PluginCafé
Here's the code working for materials. How would I expand it to also work with Scene Nodes and, ideally, to work with the currently active node editor?
"""Name-en-US: Select Node Children
Description-en-US: Selects Child Nodes
Copyright: MAXON Computer GmbH
Author: Donovan Keith
Adapted from a script by
Copyright: MAXON Computer GmbH
Author: Manuel Magalhaes
- v0.1.0: Initial Release
# Get the Active Material
# ISSUE: It's possible to have the node editor editing a material even if its not active/selected (Asset Mode, Lock mode, etc)
mat = doc.GetActiveMaterial()
if mat is None:
raise ValueError("There is no selected BaseMaterial")
# Retrieve the reference of the material as a node Material.
nodeMaterial = mat.GetNodeMaterialReference()
if nodeMaterial is None:
raise ValueError("Can't retrieve nodeMaterial reference")
# Retrieve the current node space Id
nodespaceId = c4d.GetActiveNodeSpaceId()
# Retrieve the graph corresponding to that nodeSpace.
graph = nodeMaterial.GetGraph(nodespaceId)
if graph is None:
raise ValueError("Can't retrieve the graph of this nimbus ref")
with graph.BeginTransaction() as transaction:
selected_nodes = 
maxon.GraphModelHelper.GetSelectedNodes(graph, maxon.NODE_KIND.NODE, selected_nodes)
predecessors = 
for node in selected_nodes:
maxon.GraphModelHelper.GetAllPredecessors(node, maxon.NODE_KIND.NODE, predecessors)
for predecessor in predecessors:
# Pushes an update event to Cinema 4D
if __name__ == "__main__":
Is there a way to access the current/active graph in the Node Editor via the Python API? I'm trying to write some node layout helpers (Align Horizontal/Vertical) but I'm not finding the information I'm looking for.
Wow! What an incredible set of answers. You've each addressed a different thing I intended to do with these polygon groups once I had access to them.
Thank you @ferdinand @m_adam and @pyr!
Is there an available convenience method for getting all polygon islands in a polygon object? It seems like one exists internally for things like the Texture > View > Multi-Color Islands option.
Texture > View > Multi-Color Islands
Specifically, I'm looking for polygon islands/shells, but an additional command/option for UV Islands would be great too.
If one doesn't exist, I'd like to request that one be added to the Python SDK.
I'm trying to export object an animated hierarchy of objects from Cinema 4D's left coordinates (z+ = forward) with HPB rotations to Three.js's right-hand coordinates (z+ = backward) with XYZ rotations.
Unfortunately, I'm a bit beyond my depth with the matrix math and conversions involved. I'd like to take my C4D local coords write them out as local coords in this other system.
Any tips on how to approach this?
PS: Looks like we need an S22 tag in the tags option.