Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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
    • Recent
    • Tags
    • Users
    • Login

    Python | Force obj to calc b4 another obj

    Scheduled Pinned Locked Moved PYTHON Development
    17 Posts 0 Posters 1.2k Views
    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 Offline
      Helper
      last edited by

      On 06/05/2013 at 12:37, xxxxxxxx wrote:

      Thankyou for that, Ferdinand (did I get your name correct?),

      For GetNodeData(), I can ask for this and it returns what?  a Dict with all the Ivars or method names? Or basically pass the "op"?  So can I call functions on another plugin with this? If so, it would force the order perfectly as it would make it run the function and get the result before moving on which would be perfect.

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

        On 06/05/2013 at 13:00, xxxxxxxx wrote:

        Hi Chris,

        no this will not change the order of execution. But it allows you to change any data (such as
        the values of instance variables that are not shown in the description of an object). You have to
        get the priorities right. Cinema executes generators sequentially, so if you want the one generator
        to be finished before the other, you have to put the one in a higher position than the other.

        Another way would be to calculate the data in an Execute() pass and retrieve this information
        in GetVirtualObjects(). But I think this would disallow you to use objects as input (children, like
        the HyperNURBS for example uses it's child-object as input). If this is a requirement, it will probably
        not be an option.

        Best,
        -Niklas

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

          On 06/05/2013 at 13:09, xxxxxxxx wrote:

          hi,

          yes my name is Ferdinand. GetNodeData() returns the NodeData implentation attached to a 
          GeListNode. If you have an ObjectData plugin which implements something like that :

          ObjectDataData(plugins.ObjectData) :
          	def __init__(self) :
          		self.someFancyList = []
          	[...]
          	def GetVirtualObjects(self, node, hh) :
          	[...]
          

          it will return an instance of ObjectDataData attached to that GeListNode so that you acccess
          ObjectDataData.someFancyList attached to that GeListNode. For native c4d objects (that are 
          not implemented as a plugin) it will return None. You can try it from the console, simply drag a 
          plugin node into it and put a .GetNodedata() behind it.

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

            On 06/05/2013 at 13:14, xxxxxxxx wrote:

            Ferdinand, I don't have a Python Object Plugin to hand, but using GetNodeData() on a non-Python
            plugin object doesn't work (it returns None). I didn't test it for Python object plugins, but I assume it
            only works for those (would be pretty much senseless if it would always return None).

            Anyway, good catch that this method is actually available, didn't see it until now.

            Best,
            -Niklas

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

              On 06/05/2013 at 13:19, xxxxxxxx wrote:

              Originally posted by xxxxxxxx

              You have to get the priorities right. Cinema executes generators sequentially ...

              are you sure about that ? c4d obviously passes the objects sequentially, or in other
              words works its way down the object manager, but as i already wrote above, as
              BaseObject.GVO(), BaseTag.Execute() and so on are all threaded, should it not be 
              possible to 'wait' for other objects to be updated ?

              edit: is does work, i am using it. not sure why it is not documented. as i am exclusively
              python right now, except from our polylight cpp excursion, i haven't bothered testing it
              cross language yet, but you are right it does not work (which is not really surprising IMHO).

              [OK] fhArraySampleObject.GetNodeData()
              <__main__.fhArraySampleObjectData object at 0x000000000FA193F0>
              [OK] hook = fhVertexmapShade.GetNodeData()
              [OK] dir(hook)
              ['Draw', 'Execute', 'FakeMaterial', 'GetDEnabling', 'Init', 'InitAttr', 'IsInit', 'IsInstanceOf', 'IsRenderDirty', 'Message', 'Sampler', 'ShaderContainerCache', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'initHost', 'isDirty']
              [OK] print hook.IsRenderDirty
              False
              

              edit2: first one is an ObjectData, second one is a TagData. i did extend the example a bit,
              mainly for the op.

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

                On 06/05/2013 at 13:43, xxxxxxxx wrote:

                This is all pure gold.  Thank you both.  I appreciate both of your assistance greatly.  I'll reply with any succsesses.

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

                  On 06/05/2013 at 13:56, xxxxxxxx wrote:

                  Originally posted by xxxxxxxx

                  Originally posted by xxxxxxxx

                  You have to get the priorities right. Cinema executes generators sequentially ...

                  are you sure about that ? c4d obviously passes the objects sequentially, or in other
                  words works its way down the object manager, but as i already wrote above, as
                  BaseObject.GVO(), BaseTag.Execute() and so on are all threaded, should it not be 
                  possible to 'wait' for other objects to be updated ?

                  I'm also thinking about this. I'm not 100% sure about this, but it would be the only explanation
                  to the behavior I have experienced so far.

                  Even if it would be possible for you to wait until another object has been updated (assuming
                  it is being updated from another thread), you would block the thread of your object. 🙂

                  And to extend your example a bit more 🙂

                  [OK] print Cube.GetNodeData()
                  None
                  

                  Best,
                  -Niklas

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

                    On 06/05/2013 at 17:17, xxxxxxxx wrote:

                    I AM BLOWN AWAY

                    Works flawlessly.  Instead of storing my variable as a hidden description, I wrote a "getter" method on my other plugins.  On my main plugin when I needed the data I asked for the NodeData and called that function that did the calculation on the other plugin on demand and all of the frame lag and glitching is completely gone.  Works FLAWLESSLY.

                    I am blown away it works so well.  I'm also excited as I've had other "glitchy" bugs all related to passing values through Descriptions.  And when I switch them to "getter" methods through NodeData, I'm confident it will solve those as well.

                    Again, thank you both for this help.  Priceless.

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

                      On 06/05/2013 at 17:46, xxxxxxxx wrote:

                      ^Can you please post an example how you are getting your other plugin?

                      To grab tag plugins I use something like this: tag = obj.GetTag(TAG_PLUGIN_ID);
                      I don't make ObjectData plugins very often. So I'm wondering if grabbing an ObjectData plugin is done differently than getting a tag plugin from within another plugin?

                      -ScottA

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

                        On 06/05/2013 at 17:58, xxxxxxxx wrote:

                        Sure.  This isn't from my plug but a simple example of what I just did:

                        My Camera Waypoints are their own object and they are created by my main plugin.  As they are created they are populated into an incl/exl list on the main plugin.  Each Waypoint has a target position in space based on their Z direction * a depth parameter.  I was calculating this global position for depth on the Waypoint and setting a hidden description with this value which I would read on the main plugin.  However since the 2 objects are in different threads, this was often calculated AFTER the main plugin causing lag and glitching.  SO, on the main plugin instead of getting the waypoint as an object from the list and doing a :

                        tpos = cam[c4d.TARGETPOS]
                        

                        I moved my code on the waypoint into a functioncalled "getTPos()" that gathers all the info needed there and returned the value from the method itself.  SO, on my main plugin I did:

                        camdata = cam.GetNodeData()
                        tpos = camdata.getTPos()
                        

                        Which forced the waypoint to collect all the data that moment before my main plug carried on further.  Insuring the data would always be calculated when asked.  Before when it was calculated on it's own in it's own thread and placed in a description it was usually behind or on occasion ahead which create a glitch or lag.

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

                          On 06/05/2013 at 18:03, xxxxxxxx wrote:

                          Looking at your question again, Scott, you may have been asking how to reference your other plugin as opposed to the GetNodeData part.  Mine are always in a exl list so I just loop through that getting data on each.  Although I suppose you can just do the usual way of referencing other objects but for type you use your plugin ID.  Not sure if that's what you mean.

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

                            On 06/05/2013 at 18:33, xxxxxxxx wrote:

                            Yeah.
                            I meant getting an ObjectData plugin from inside a different plugin. So I could then get at all of the ObjectData's members.
                            It's handy to be able to have two plugins talk to each other internally like that.
                            I've done this with tag and Gedialog plugins. But not ObjectData plugins yet.

                            I thought that's what you were dong. But I guess not.

                            Thanks anyway.
                            -ScottA

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