Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Where is information on the Python Tag?

    PYTHON Development
    0
    20
    3.6k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      On 10/02/2018 at 04:50, xxxxxxxx wrote:

      Hi,
      I have been trying to find information specific about the Python tag, without success.
      Is there dedicated documentation about it?

      Cheers
      Thanassis

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 12/02/2018 at 05:26, xxxxxxxx wrote:

        Hi Thanassis,

        no, there's actually no special documentation for the Python Tag. What information are you looking for?

        In the end the Python Tag is a normal TagData plugin, where the Execute() function is exposed to the user and can be implemented via Python.

        So, the usual rules for NodeData plugins and threaded functions apply for the tag as well.
        - do NOT use GetActiveDocument() (but instead get the document from the tag or host object via GetDocument())
        - do NOT modify the scene (inserting, deleting objects, changing the hierarchy,...), instead only influence the host objects parameters
        - no need for EventAdd(), opposed to scripts in Script Manager or CommandData plugins

        Like in other places in Cinema 4D, there are a few global variables defined for convenience:
        - doc - The document the tag belongs to or is inserted in
        - op - Referring to the Python tag itself, use GetObject() to get the host object
        - flags - The execution flags, see TagData.Execute() parameter description
        - priority - The execution priority, see TagData.Execute() parameter description
        - bt - a BaseThread - private, not in use, see TagData.Execute() parameter description
        - tp - the Thinking Particles master system

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 12/02/2018 at 06:20, xxxxxxxx wrote:

          Thanks Andreas,
          I still have a few questions though.

          1. Adding objects is allowed, as I have seen it working. Is it advised against, or it shouldn't work in the first place?
          2. Does each Python node have a Unique identifier, equivalent to the GUID() for objects?

          My overall query is because I'm trying to make a Python node that outputs the Object or Hierarchy mesh Cache of an input so I can feed it into various XPRESSO nodes that by default don't accept anything else.
          e.g. Matterwaves e.t.c.

          Thanks

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 12/02/2018 at 08:26, xxxxxxxx wrote:

            Since when are we talking about an Xpresso Python Scripting node?

            And no, a Python tag is not supposed to insert objects into the scene. It is not only not recommended, it is forbidden. The outcome of such wrong behavior is pretty much undetermined, there may be scenes, where it seems to work, in others it crashes immediately and in the rest it may have strange side effects on other parts of the scene. It is forbidden, full stop.

            The correct or recommended way for creating an object is to assign the new object to an output of a Python Scripting node and then connect it an object node.

            Xpresso (or rather GraphView) nodes do not have a GUID, nor am I aware of a unique ID at all. But I'll check with the team tomorrow and will get back to you, if somebody has an idea.

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 12/02/2018 at 10:39, xxxxxxxx wrote:

              Sorry Andreas, that was another question I had in regards to the Python node... apologies for the confusion!

              Thanks for the answer, and I'd be very interested in the ID.

              Cheers
              T

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 13/02/2018 at 05:43, xxxxxxxx wrote:

                Hi Thanassis,

                no need to apologize, by now I'm pretty used to being tricked into your pitfalls... 😉

                Regarding IDs it's a bit unfortunate. GvNode does not support GUIDs and GeMarker (link to C++ docs) is not available in Python. I guess, the only option is to do it manually with AddUniqueID() and FindUniqueID().
                May I ask, what you are planning to do with this such ID?

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 13/02/2018 at 05:58, xxxxxxxx wrote:

                  Originally posted by xxxxxxxx

                  May I ask, what you are planning to do with this such ID?

                  As I mentioned earlier, I am trying to create an XPRESSO node that allows any object to be used as an input, as if it was a mesh object (for example Matterwaves).
                  A little birdie, wrote me a Python Node that creates a hidden mesh object from any input. It works great if are using only one of these nodes is in the Graph, but once you use another one, you get conflicting meshes.
                  I want to be able to name the hidden mesh with a unique name for each of the python nodes.

                  Fast forward yesterday, and I realized I can do that using the input object's GUID, since it's NOT the node's uniqueness I'm really interested in, but the input object's.

                  I'll send you the scene privately, and when it works as expected, I'll release it to the Public for free, as usual 🙂

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    On 13/02/2018 at 06:10, xxxxxxxx wrote:

                    Before I send anything, I would like to try by myself something first.
                    I was trying to use SearchObject() to find and delete an object from my scene, but I was getting an error.
                    Can I use the syntax: doc.SearchObject(somename).Remove() within a Python Node, or do I need to do something else first?

                    Cheers
                    T

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 13/02/2018 at 06:13, xxxxxxxx wrote:

                      As mentioned earlier in this thread, Python node shouldn't modify the scene directly, either. It should rather work into an object node.

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 13/02/2018 at 06:32, xxxxxxxx wrote:

                        ok, Im confused.
                        I thought you said "Python Tag" doesn't modify the scene.
                        Not Python XPRESSO node.

                        Anyway, I managed to make this work, so it seems...
                        Here's the file link:
                        https://www.dropbox.com/s/tmhw3x0rjh55onl/Object Cache 99A Troubleshooting 03A.c4d?dl=0

                        1 Reply Last reply Reply Quote 0
                        • H
                          Helper
                          last edited by

                          On 13/02/2018 at 06:48, xxxxxxxx wrote:

                          The correct or recommended way for creating an object is to assign the new object to an output of a Python Scripting node and then connect it an object node.

                          1 Reply Last reply Reply Quote 0
                          • H
                            Helper
                            last edited by

                            On 13/02/2018 at 06:54, xxxxxxxx wrote:

                            Originally posted by xxxxxxxx

                            The correct or recommended way for creating an object is to assign the new object to an output of a Python Scripting node and then connect it an object node.

                            But this defeats the "simple" nature of what I'm aiming to do.
                            What issues could I expect from the current implementation?

                            Cheers
                            T

                            ..
                            p.s. here's a version with slightly different code.
                            The "doc.SearchObject(uniqueName)" is now assigned to a variable.

                            http://https://www.dropbox.com/s/fha59mg21p9m1ru/Object Cache 99A Troubleshooting 05A.c4d?dl=0

                            1 Reply Last reply Reply Quote 0
                            • H
                              Helper
                              last edited by

                              On 15/02/2018 at 02:48, xxxxxxxx wrote:

                              Hi,

                              sorry, to let you wait.
                              And I'm also sorry, this is not as easy, as you wished. Since when are you scared by challenges?
                              Xpresso is being executed/evaluated during scene execution. Nothing/nobody is supposed to change the scene during execution.

                              The resulting issues range from priority or updating issues to crashes. There's no "works always" or "fails exactly with this issue" here. It may even work for quite some time without issues, but then with the correct scene, it suddenly destroys the user's work. So, no, we can not recommend it.

                              How about implementing a command, which creates the needed nodes and objects in one go? Basically creating a hidden object (or just on a special layer?), the Python node (with code and object output port) and an object node connected to it? A bit more work and yes, not the "perfect" workflow you had in mind, but instead safe.

                              1 Reply Last reply Reply Quote 0
                              • H
                                Helper
                                last edited by

                                On 15/02/2018 at 05:15, xxxxxxxx wrote:

                                I'm always scared of challenges. I just hide it well 🙂

                                I was aware that it's not allowed to change the scene during execution, but I thought it was something you "Couldn't" do, not "Shouldn't" do. So, when I saw this node working, I was pleasantly surprised. 🙂

                                The funny thing is that a "poor man's" version of this node is possible with very simple code, but only works with simple generators and primitives:

                                import c4d
                                def main() :
                                global MeshObject
                                MeshObject = Object.GetCache()

                                So my questions are:
                                1. Is this allowed (the poor man's code)?
                                2. Can the previous node (the complex one) be written so that the data is not an object, but a Cache that lives in memory just like the small version.

                                Thanks as always Andreas!
                                T

                                1 Reply Last reply Reply Quote 0
                                • H
                                  Helper
                                  last edited by

                                  On 15/02/2018 at 06:31, xxxxxxxx wrote:

                                  Actually in your "poor man's" version, you are returning an object (or are delivering an object to the output). A cache is nothing else but a PolygonObject. As long as you can work with it without inserting it into the scene, you are fine.

                                  1 Reply Last reply Reply Quote 0
                                  • H
                                    Helper
                                    last edited by

                                    On 15/02/2018 at 07:40, xxxxxxxx wrote:

                                    So, as a dumbed-down rule of thumb, as long as doc.InsertObject(obj) is NOT in the code, it should be safe to proceed?
                                    Are there any other ways to insert objects I should try to avoid?

                                    Cheers
                                    T

                                    1 Reply Last reply Reply Quote 0
                                    • H
                                      Helper
                                      last edited by

                                      On 15/02/2018 at 09:06, xxxxxxxx wrote:

                                      Well, all types of inserting something into the scene, like InsertMaterial(), InsertTag(), ...
                                      This includes also all kinds of GeListNode.InsertX() functions (e.g. InsertAfter()) on entities that are already part of the scene.
                                      And of course the corresponding Remove() functions.
                                      Basically everything that alters the scene tree.

                                      1 Reply Last reply Reply Quote 0
                                      • H
                                        Helper
                                        last edited by

                                        On 15/02/2018 at 09:44, xxxxxxxx wrote:

                                        Nice. "insert" and "delete" are the main things to try to avoid, but passing the cache of an object to a node input doesn't mean the scene is altered. Is that a correct assumption?
                                        Also, can I assume that as long as an Event Add doesn't add or remove anything in my Object manager, I'm generally moving in the right direction?
                                        Cheers
                                        T

                                        1 Reply Last reply Reply Quote 0
                                        • H
                                          Helper
                                          last edited by

                                          On 16/02/2018 at 04:32, xxxxxxxx wrote:

                                          Yes, the assumption is correct. You'd feed the object into an Object node, in order to introduce it to the scene.

                                          EventAdd() doesn't change anything itself. It's an event being posted, that informs other parts of Cinema 4D, something (!) has changed. The other parts will then check, if anything relevant for them has changed and act accordingly. But it's not like, an object is only inserted into the scene, after you called EventAdd(). It is actually inserted on the "Insert()" call, it just doesn't show up to the user, because a UI update is still missing in the Object Manager (which is then triggered later on by EventAdd().

                                          By the way, EventAdd() is another function that shouldn't be called in NodeData derived plugins, especially not in execution or drawing pipeline.

                                          1 Reply Last reply Reply Quote 0
                                          • H
                                            Helper
                                            last edited by

                                            On 16/02/2018 at 04:41, xxxxxxxx wrote:

                                            Thanks Andreas.

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post