Get information about BasePlugin
-
Hi Everyone!
Currently I'm recreating the Command Manager Dialog in Cinema4D, because I need to drag and drop these commands to other plase in my plugin.
And I have some questions:-
Is there a shortway to get all the commands in Command Mnager directly? because the
plugins.FilterPluginList(PLUGINTYPE_ANY)
give everything in cinema , it have some folders, and some commands are repeated, the plugin id is same but diffrent plugin type and diffrent info, some commands do not have names, I'm a little confused in this situation. -
if there are no shortway to get all commands in Command Manager, How do I get the information in the plugin column in Command Manager?
-
-
Hello @gheyret,
Thank you for reaching out to us. I am not quite sure I understand your issue correctly.
FilterPluginList
allows you to filter by type, to get all command plugins, just passPLUGINTYPE_COMMAND
.- The column Plugin you have highlighted is internally usually called managergroupp. A better name would probably be context or owner as it denotes the owner of a command.
It can for once be retrieved with(not correct, see below).MSG_COMMANDINFORMATION
as pointed out by @m_adam here. I assume the workflow he envisioned there was to send this message to theBasePlugin
nodeAn alternative is to use c4d.gui.GetShortcut, it will also yield the context, i.e., the owner under which a shortcut works via c4d.SHORTCUT_ADDRESSS (the naming is an absolute mess here, but this is the manager ID)(not quite correct either, see below too). But it of course only works for things that are bound to a shortcut. For code, you could look at this older topic of yours, we did already cover the basics there.
Maybe you could clarify what you want to achieve?
Cheers,
Ferdinand -
Hi @ferdinand
I'm sorry I wasn't clear. Currently I'm using PySide to create my plugin, And my final goal is fully recreate the Command Manager Dialog, and Drag and Drop the Commands to my other UI widgets just for better experience.I have created a user interface similar to a command manager, but I've noticed that some commands retrieved using the
plugins.FilterPluginList()
method are duplicated.
In my understanding, Plugin IDs are meant to be unique in Cinema 4D, but encountering duplicate command IDs has confused me.For example, I get three "Cloud Tool" with same ID using
plugins.FilterPluginList()
but diffrent type (tool, command, node).
While I can manually filter them, but I think this complicates the workflow unnecessarily.
So I would like to know why commands with the same ID have different types, and what their differences are.
An my second question: How do I get the information in the plugin column in Command Manager?
In Cinema 4D, many commands share the same icon and name. I believe when users search for a command by its name, encountering multiple identical commands can be confusing. Therefore, additional information about the commands is needed to help users filter them effectively. In now , I can get the icon, name, shortcut key, help string of command, but I don't know how to get "the information in the plugin column in Command Manager" or the owner like you said.
Thanks for your reply
Cheers~ -
Hey @gheyret,
For example, I get three "Cloud Tool" with same ID using plugins.FilterPluginList() but diffrent type (tool, command, node). While I can manually filter them, but I think this complicates the workflow unnecessarily.
Well, you give yourself the answer here. These three plugins are differentiated by their type. Sometimes our developers reused IDs in the past when there were multiple plugins in different categories for a feature (e.g. "Clouds"). Today this is mostly frowned upon internally, but there might be still a black sheep here and there which reuses IDs.
This shortcut/hack works, because plugin IDs technically only have to be unique within certain categories, a command ID can never collide with an shader ID for example. But you should never do what some of our developers did there in the past. Never reuse plugin IDs.
I am not quite sure what you are expecting from me here. The plugin IDs are how they are, I cannot change this at this point (it would be at least a lot of work). When you just want plugins from one category, just filter for that category as lined out above, e.g.:
# Get all command plugins. commands: list[c4d.BasePlugin] = c4d.plugins.FilterPluginList(c4d.PLUGINTYPE_COMMAND)
An my second question: How do I get the information in the plugin column in Command Manager?
I have already answered how to get the Plugin column information in my first answer.
Cheers,
Ferdinand -
Hey @ferdinand ,
Thank you for your clarification.
What I meant by the difference is what will happen when users execute commands with the same ID but different types.
How do they differ in terms of their functionality?
For instance, if executes a Tool-type Cloud Tool and Command-type Cloud Tool, what would happen in each case?
and if they perform the same function, can I then avoid manually screening them? -
This is my plugin , I promise I'm not reuse plugin id, and I can't use it, it will show that the plugin ID has been registered
But I get this: (It's a TagData Plugin, but I can get another Command-Type here.)
So many Object, Tool and Tag type plugins have a command type.
-
Hey @gheyret,
well, there is a lot of things going on in the underbelly of Cinema 4D and you are confronted with it here and this is also somewhat out of scope of support as this reaches into our internals.
First of all, pretty much every node requires a command. I.e., when you for example implement the
ObjectData
pluginOfancycubes
, there must be a button, a.k.a. "a command", in Cinema 4D with which a user can create a "Fancy Cubes" object. The command manager just shows you commands as its name says. So, when you find there for example the "Cloud Tool", that is not the tool, but the command that wraps the tool so that users can actually use it. The plugin node in this case is just theBasePlugin
node I think (did not test it). Some of these duplicates are generated automatically like for example a command which wraps an object, tag, shader, etc or the node which wraps the plugin. But some of them have been created manually in the ancient past of Cinema 4D. There is no one and only way to sort out what is relevant and what not, as this depends on what you want to do.
Fig. I: When you search for the cloud tool in the command manager, it actually shows you the command for the tool, not the tool itself despite saying otherwise. Pretty much every tangible thing in Cinema 4D has a command.I also had a go myself at the problem with the plugin column, and I most correct myself a bit. What @m_adam suggested is not possible, as
MSG_COMMANDINFORMATION
is only an ingoing message, you cannot send it yourself. TheSHORTCUT_ADDRESSS
also expresses a different context than I thought, i.e., it only gives you the window manager, and not the plugin owner, e..g., "Sky". I currently do not see a way to access this information in Python.Cheers,
FerdinandResult
Add Nodes... (ID: 200001021, Owner: Node Editor) Arrange All Nodes (ID: 465002363, Owner: Node Editor) Arrange Selected Nodes (ID: 465002311, Owner: Node Editor) Auto Tangents - Classic (ID: 465001102, Owner: Timeline) Auto Zoom Mode (ID: 430000774, Owner: Picture Viewer) Automatic Mode (ID: 465001037, Owner: Timeline) Break Tangents (ID: 465001103, Owner: Timeline) Browser Preferences... (ID: 1057913, Owner: Asset Browser) Center Selected (ID: 465002308, Owner: Node Editor) Clamp (ID: 465001110, Owner: Timeline) Commander (ID: 1040216, Owner: RS Shader Graph Editor) Delete (ID: 1057998, Owner: Asset Browser) Delete Scaffold and Contents (ID: 465002390, Owner: Node Editor) Ease Ease (ID: 465001095, Owner: Timeline) Ease In (ID: 465001094, Owner: Timeline) Ease Out (ID: 465001096, Owner: Timeline) Enable Frame Snapping (ID: 465001075, Owner: Timeline) Fit to Screen (ID: 170025, Owner: Texture View) Frame All (ID: 1034014, Owner: Motion Tracker Graph View Manager) Frame All (ID: 465001032, Owner: Timeline) Frame All (ID: 465002300, Owner: Node Editor) Frame Preview Range (ID: 465001028, Owner: Timeline) Frame Selected (ID: 465001017, Owner: Timeline) Frame Selected (ID: 1034015, Owner: Motion Tracker Graph View Manager) Frame Selected (ID: 465002307, Owner: Node Editor) Frame Selected UV Elements (ID: 170781, Owner: Texture View) Frame Selected UV Islands (ID: 170782, Owner: Texture View) Full-Screen Mode (ID: 465001761, Owner: Picture Viewer) Go to Current Frame (ID: 1034016, Owner: Motion Tracker Graph View Manager) Go to Current Frame (ID: 465001016, Owner: Timeline) Go to End (ID: 465001019, Owner: Timeline) Go to First Key/Motion Clip (ID: 465001026, Owner: Timeline) Go to First Marker (ID: 465001127, Owner: Timeline) Go to Last Key/Motion Clip (ID: 465001027, Owner: Timeline) Go to Last Marker (ID: 465001128, Owner: Timeline) Go to Next Image (ID: 430000746, Owner: Picture Viewer) Go to Next Key (ID: 465001024, Owner: Timeline) Go to Next Marker (ID: 465001022, Owner: Timeline) Go to Previous Image (ID: 430000742, Owner: Picture Viewer) Go to Previous Key (ID: 465001025, Owner: Timeline) Go to Previous Marker (ID: 465001023, Owner: Timeline) Go to Start (ID: 465001018, Owner: Timeline) Group In Scaffold... (ID: 465002322, Owner: Node Editor) Group Nodes (ID: 465002302, Owner: Node Editor) Key/F-Curve/Motion Mode (ID: 465001129, Owner: Timeline) Linear (ID: 465001092, Owner: Timeline) Merge Objects... (ID: 100004764, Owner: Object Manager) New Default Material (ID: 1057358, Owner: Object Manager) New Node Material (ID: 1057382, Owner: Object Manager) New Node Material (ID: 202541, Owner: Material Manager) New Note (ID: 465002403, Owner: Node Editor) Open Duplicated Browser (ID: 1056623, Owner: Asset Browser) Open Image... (ID: 430000730, Owner: Picture Viewer) Output Geometry (ID: 1062059, Owner: Node Editor) Play Forwards (ID: 430000745, Owner: Picture Viewer) Play Forwards (ID: 465001318, Owner: Timeline) Record Current State (ID: 465001001, Owner: Timeline) Region Tool (ID: 465001004, Owner: Timeline) Rename... (ID: 1056624, Owner: Asset Browser) Ripple Edit (ID: 465001005, Owner: Timeline) Save Image as... (ID: 465001707, Owner: Picture Viewer) Scroll to Selection (ID: 100004769, Owner: Object Manager) Search (ID: 1058001, Owner: Asset Browser) Select All Nodes (ID: 465002309, Owner: Node Editor) Select Connected Nodes (ID: 465002316, Owner: Node Editor) Select Downstream Nodes (ID: 465002318, Owner: Node Editor) Set as A (ID: 430000768, Owner: Picture Viewer) Set as B (ID: 430000769, Owner: Picture Viewer) Set as Preview End (ID: 465001727, Owner: Picture Viewer) Set as Preview Start (ID: 465001726, Owner: Picture Viewer) Show Filter (ID: 465001046, Owner: Timeline) Show Filter (ID: 100004746, Owner: Object Manager) Show Search Bar (ID: 100004762, Owner: Object Manager) Show Search Bar (ID: 465001045, Owner: Timeline) Soft (ID: 465001091, Owner: Timeline) Step (ID: 465001093, Owner: Timeline) Swap AB (ID: 430000767, Owner: Picture Viewer) Timeline Preferences (ID: 465001007, Owner: Timeline) Toggle Active View (ID: 13640, Owner: Viewport) Ungroup Nodes (ID: 465002313, Owner: Node Editor) Ungroup Objects (ID: 100004773, Owner: Object Manager) UV Transform (ID: 1038963, Owner: Texture View) Zero Angle (Tangent) (ID: 465001106, Owner: Timeline) Zero Length (Tangent) (ID: 465001107, Owner: Timeline) Zoom In (ID: 430000782, Owner: Picture Viewer) Zoom In (ID: 465002325, Owner: Node Editor) Zoom Out (ID: 430000783, Owner: Picture Viewer) Zoom Out (ID: 465002326, Owner: Node Editor)
Code
import c4d def GetPluginOwner(pid: int) -> int: """Attempts to find the owner of the owner of the command plugin with the given #pid via the shortcuts. Returns NOTOK if the owner could not be found. """ for i in range(c4d.gui.GetShortcutCount()): shortcut: c4d.BaseContainer = c4d.gui.GetShortcut(i) if shortcut[c4d.SHORTCUT_PLUGINID] == pid: return shortcut[c4d.SHORTCUT_ADDRESS] return c4d.NOTOK def main() -> None: """Called by Cinema 4D when the script is being executed. """ command: c4d.BasePlugin for command in c4d.plugins.FilterPluginList(c4d.PLUGINTYPE_COMMAND, True): name: str = command.GetName() # We ignore commands without a label or which are hidden. if not name or command.GetInfo() & c4d.PLUGINFLAG_HIDE: continue # Try to the owner of the command plugin via the shortcuts. What Maxime proposed there does # not work, as the message MSG_GETCOMMANDINFO is only an ingoing message for plugin hooks, # we cannot send it ourself (see docs, it is lined out there). owner: int = GetPluginOwner(command.GetID()) owner: c4d.BasePlugin | None = c4d.plugins.FindPlugin(owner) ownerName: str = None if not owner else owner.GetName() if ownerName: print(f"{name} (ID: {command.GetID()}, Owner: {ownerName})") if __name__ == '__main__': main()
-
Thanks for your explaination @ferdinand
Now I understand what's going on here.Cheers!