Adding an object in the Xpresso Editor by a "button" rather than dragging from object manager


#1

Hi,

Is there a way to add an object to the Xpresso Editor by a button? (For instance in Maya, we just click on an object in the viewport and click a plus icon and then that node appears in the Node Editor).

Currently, the only method I know in C4D is by dragging from object manager to viewport.
It works but it becomes annoying when I have to unfold all the hierarchies just to be able to drag it to the object manager.

Is there a way around this?

Thank you

P.S. If you are suggesting pressing “S” to immediately locate an object in the object manager, that may work for simple hierarchies. However, when I rig, the fully extended hierarchies almost always occupies a third of my screen. So I have to adjust my the size object manager to accommodate every now and then. (which as you might see, counterproductive).


#2

There is a way to do what you describe via script or plugin.
However, due to design and the available SDK functions, the script/plugin will need to know to which Xpresso window you want your object to be added to.

Note that each Xpresso tag can have its own window open. By manually dragging the object into an Xpresso window you are actually telling Cinema 4D which Xpresso tag you want the object to be added to. Additionally, by manually dragging you also indicate where in the window you want your node to appear.

So, yes it’s possible via script. But you’ll need some “setup” to indicate the script which Xpresso tag to use.
Assume you have your Xpresso tag assigned to a null at the top of Object Manager, then the script would simply need to pick the top object from the list, get its Xpresso tag … and done.
If your Xpresso tag is somewhere deep down in your object hierarchy, then things get more complicated and you’ll need to setup the “find and use this Xpresso tag”.
If you then would like to use this workflow with different Xpresso tags you will need to adjust the “find and use …” each time you want to target a different Xpresso tag.
Might lead to a more troublesome workflow than the current drag-n-drop.

But if you’re happy with the above limitations, I could provide you with a basic script.


#3

Hi @C4DS
A script would be nice but I do get the conundrum regarding specifying an Xpresso Tag.

Is it possible to identify the Xpresso per name for instance an Xpresso with the name “mainXpresso”?


#4

Sure, you could give the Xpresso tag a specific name, and let the script look for that.
Or you could let the script look for a specifically named object, where the Xpresso tag is assigned to.

More exotically, you could even add a custom “something” to the object hosting your Xpresso tag.
That “something” could be:

  • a custom tag, which you could then move to a different object if need be.
  • a specific container data stored into the object
  • a specific layer … although I am not too familiar with layers, this might require some further investigation.

#5

The “custom” something is interesting but I think it would complicate things. Didn’t know that modifying xpresso (regarding your comment on SDK) was that complicated.


#6

No, modifying the Xpresso isn’t that complicated. What I meant with “available functions” was that not all feature a user takes for granted are available via the SDK.

For instance, as a user you would not assume that it could be complicated to perform a simple drag-n-drop, the way the user does it interactively in Cinema 4D.
To my knowledge (but I honestly am not an expert) there is no way to find out the currently open Xpresso window.

To perform a simple drag-n-drop you first need the active object (= OK), then you need to know where to drag it to. And here is the problem … when you cannot obtain the current active Xpresso window, where do you drag the object to?

So, “simple” things are not always simple to script.


#7

As long as you are happy with the limitation, it’s not all that difficult. First, the tag is searched for, then a new node is added to that tag’s node master, and in this node the currently active element is set as reference:

import c4d
from c4d import gui
#Add to XPresso


def traverseTaglist(tag):
    while tag != None:
        if tag.GetName() == "mainXPresso" : return tag
        tag=tag.GetNext()
    return None

def traverseTree(obj):
    while obj != None:
        xtag = traverseTaglist(obj.GetFirstTag())
        if xtag != None : return xtag
        xtag = traverseTree(obj.GetDown())
        if xtag != None : return xtag
        obj=obj.GetNext()
    return None

def main():
    root = doc.GetFirstObject()
    xtag = traverseTree(root)
    if xtag == None : 
        print "Tag mainXPresso not found!"
    nodemaster = xtag.GetNodeMaster()
    if nodemaster != None :
        objectnode = nodemaster.CreateNode(nodemaster.GetRoot(), c4d.ID_OPERATOR_OBJECT, None, 50, 50)
        if objectnode != None :
            nodemaster.InsertLast(nodemaster.GetRoot(), objectnode)
            objectnode[c4d.GV_OBJECT_OBJECT_ID] = doc.GetActiveObject()
            c4d.EventAdd()
    

if __name__=='__main__':
    main()

Note that this script doesn’t update the X-Manager. I haven’t found the proper way…

C4DS is right though, the API does not provide nearly enough functionality to handle the GUI windows. This also affects any object manager functionality. I hope this will be added in the future.


#8

@C4DS

Oh I see what you mean. I never thought of it that way. Thanks for clearing things up

@Cairyn

Thanks for the script. It works as expected.

RE: Note that this script doesn’t update the X-Manager. I haven’t found the proper way…

It updates on my end :slight_smile:

Thanks again for the replies!