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
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    AddNodeToCalculationTable fails in R16

    SDK Help
    0
    12
    1.1k
    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 12/09/2015 at 10:31, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   16+ 
      Platform:   Windows  ;   
      Language(s) :     C++  ;

      ---------
      Hi,

      I have an Xpresso node that worked just fine in R13-R15. Now I have recompiled it with the R16 SDK and it stopped working.

      The node has several inports. One of them is a static port taking an integer. Now, if that port has no connection AddNodeToCalculationTable returns true and the Calculate function is correspondingly called. BUT as soon as I make a connection there (integer is coming from a C4D iterator output) AddNodeToCalculationTable fails and Calculate is never called subsequently.

      Any idea what it could be? Any help is highly appreciated.
      Here is the base code of the node:

      node.h

        
      class XParticleEditNode : public GvOperatorData  
      {  
        // Defines super  
        INSTANCEOF(XParticleEditNode, GvOperatorData)  
      public:  
        virtual Bool AddToCalculationTable    (GvNode *bn, GvRun *r);  
        virtual Bool iCreateOperator        (GvNode *bn);  
        
        virtual Bool iGetPortDescription    (GvNode* bn, GvPortIO port, Int32_C4D id, GvPortDescription* pd);  
        virtual Bool GetDDescription        (GeListNode *node, Description *description, DESCFLAGS_DESC &flags);  
        
        Bool InitCalculation(GvNode *bn, GvCalc *c, GvRun *r);  
        Bool Calculate(GvNode *bn, GvPort *port, GvRun *run, GvCalc *calc);  
        void FreeCalculation(GvNode *bn, GvCalc *c);  
          
        static NodeData* Alloc(void)  
        {  
            return new_c4d(XParticleEditNode);  
        }  
        
      private:  
        GvValuesInfo ports;  
      };
      

      node.cpp

        
      Bool XParticleEditNode::iCreateOperator(GvNode *bn)  
      {  
        BaseContainer* data = bn->GetOpContainerInstance();  
        if (!data) return FALSE;  
        
        data->SetInt64 (XPARTICLE_EDIT_INDEX,0);  
        return SUPER::iCreateOperator(bn);  
      }  
      Bool XParticleEditNode::AddToCalculationTable(GvNode *bn, GvRun *r)  
      {  
        Bool res = r->AddNodeToCalculationTable(bn); //RETURNS 0 if there is a connection at static port  
        return res;  
      }  
        
      Bool XParticleEditNode::Calculate(GvNode *bn, GvPort *port, GvRun *run, GvCalc *calc)  
      {  
        //NEVER GETS HERE WHEN THERE IS A CONNECTION AT THE STATIC PORT  
        
        return TRUE;  
      }  
        
      Bool XParticleEditNode::iGetPortDescription(GvNode* bn, GvPortIO port, Int32_C4D id, GvPortDescription* pd)  
      {  
        if(!SUPER::iGetPortDescription(bn,port,id,pd)) return false;  
        
        return true;  
      }  
        
      Bool XParticleEditNode::GetDDescription(GeListNode *node, Description *description, DESCFLAGS_DESC &flags)  
      {   
        if (!description || !node) return FALSE;   
        if (!description->LoadDescription(node->GetType())) return FALSE;  
        flags |= DESCFLAGS_DESC_LOADED;  
        return SUPER::GetDDescription(node, description, flags);  
      }  
        
      Bool XParticleEditNode::InitCalculation(GvNode *bn, GvCalc *c, GvRun *r)  
      {  
        return GvBuildInValuesTable(bn, ports, c, r, GV_DEFINED_PORTS); //ALWAYS WORKS. VERIFIED VIA DEBUGGING  
      }  
        
      void XParticleEditNode::FreeCalculation(GvNode *bn, GvCalc *c)  
      {  
        GvFreeValuesTable(bn, ports);  
      }
      

      node.res

      CONTAINER fx_xpresso_particleedit  
      {  
         NAME fx_xpresso_particleedit;  
         INCLUDE GVbase;  
        
         GROUP ID_GVPROPERTIES  
         {      
         }  
         GROUP ID_GVPORTS  
         {  
        LONG    XPARTICLE_EDIT_INDEX    {MIN 0; INPORT; STATICPORT; CREATEPORT; }  
        
        VECTOR  XPARTICLE_EDIT_POS    {INPORT; EDITPORT; CREATEPORT;PORTONLY;}  
        
        BOOL    XPARTICLE_EDIT_ALIVE    {INPORT; EDITPORT; PORTONLY;}  
        BOOL    XPARTICLE_EDIT_COLLISION{INPORT; EDITPORT; PORTONLY;}  
        BOOL    XPARTICLE_EDIT_SPRAY    {INPORT; EDITPORT; PORTONLY;}  
        BOOL    XPARTICLE_EDIT_BUBBLE    {INPORT; EDITPORT; PORTONLY;}  
        BOOL    XPARTICLE_EDIT_TEMP    {INPORT; EDITPORT; PORTONLY;}  
          
        REAL    XPARTICLE_EDIT_PROP_SCALAR    {INPORT; MULTIPLE; PORTONLY; NOTMOVABLE;}  
        VECTOR    XPARTICLE_EDIT_PROP_VECTOR    {INPORT; MULTIPLE; PORTONLY; NOTMOVABLE;}  
        BOOL    XPARTICLE_EDIT_PROP_STATE    {INPORT; MULTIPLE; PORTONLY; NOTMOVABLE;}  
         }  
      }
      
      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 14/09/2015 at 05:00, xxxxxxxx wrote:

        btw. it doesn't matter if the port is static or not. Also no difference if I take all the other elements out (of resources) and have that one port only.

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

          On 14/09/2015 at 05:51, xxxxxxxx wrote:

          Adding a hidden dummy outport also doesn't help (was just a thought even if it was unlikely as the docs say AddToCalculationTable should be used if you want non-requesting output port behavior).

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

            On 14/09/2015 at 06:05, xxxxxxxx wrote:

            However, it DOES work if I have an outport and that one is connected to another node!
             
            So the question then is, how do I get it back that I don't need an outport (because this node is not supposed to output anything). Can I somehow set the outport to think it is connected (actually this is functionality AddToCalculationTable() should provide me with right)?

            But I would assume the node would do this automatically if there was no outport at all (guess that's what it did prior to R16?)

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

              On 14/09/2015 at 06:36, xxxxxxxx wrote:

              I overloaded SetRecalculate now as well adding the node the ctable there. It works in there!
              But the AddToCalculationTable() call still doesn't (setting force = true will result in true evaluation BUT now all nodes are called twice, so double the iteration count available...clearly this is not right and the docs also suggest not to use it. Now I know why).

              Using the efficiency display in the Xpresso editor tells me that my node is evaluated once less than the iterator (meaning one iteration is missing...which surely can be traced back to the non-working AddToCalculationTable() call). Is this supposed to be the case (that the iterator is called once more?)

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

                On 15/09/2015 at 05:43, xxxxxxxx wrote:

                Hi,

                I have some problems reproducing your issue.
                I took your code, added an Xpresso tag to a cube, created your Xpresso node. it doesn't matter if I connect anything to index, AddNodeToCalculationTable() returns true and Calculate() is called. I tried this in R16 (16.051) and R17. I also checked the code in C4D and did not find any obvious changes to the code.
                Now the only thing I can think of, that may be different between my and your version is the registration of the node. I used the following:

                GvRegisterOperatorPlugin(MY_ID, String("AddToCalculationTable Test"), GV_OPERATORFLAG_NONE, XParticleEditNode::Alloc, "fx_xpresso_particleedit", 0, ID_GV_OPCLASS_TYPE_GENERAL, ID_GV_OPGROUP_TYPE_GENERAL, 0, nullptr);
                

                Which version of C4D are you using?
                Or is it my test scenario, that's making the difference?

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

                  On 15/09/2015 at 05:52, xxxxxxxx wrote:

                  Hi Andreas,

                  thanks for the answer. I am in R16.051.

                  1. Did you try to connect a c4d iterator node to the index? Still no issue?
                  2. I register it the same way except that I have my own node classes:
                  GvRegisterOperatorPlugin(plugin_id, node_name, 0, XParticleEditNode::Alloc, "fx_xpresso_particleedit", 0, MY_OPCLASS, MY_OPGROUP, 0, icon);

                  However, I have a few other nodes that do work just fine so it cannot be the custom op class/group (which shouldn't have an effect on the execution anyway as it's just a RMB menu description handler).

                  I try the general groups just to be sure.

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

                    On 15/09/2015 at 05:54, xxxxxxxx wrote:

                    I don't think, you need to test different groups. I agree with you, these won't have any influence.

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

                      On 15/09/2015 at 05:57, xxxxxxxx wrote:

                      Got it, the iterator makes the difference. Sorry, I missed that part in your first post.

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

                        On 15/09/2015 at 06:00, xxxxxxxx wrote:

                        Nope, makes no difference here if I use general op class/group ids instead. Also I don't think it's your scenario. I am on a null object and have the iterator and my node only. Still, when I move on 1 frame the iterator is called once (though I have set 4 iterations) and my node is called 0 times (AddNodeToCalculationTable always returning false). I used no extra code beside the one I posted above (I took all the implementation details out just to be sure)

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

                          On 15/09/2015 at 06:01, xxxxxxxx wrote:

                          Oh gosh, thanks for confirming. I thought I was getting crazy! 🙂

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

                            On 15/09/2015 at 06:08, xxxxxxxx wrote:

                            ok, so I guess that means SetRecalculate is indeed required for supporting iterator node inputs in R16+ and that the missing iteration I mentioned is supposed to be that way.

                            With caution I would say you can mark this as resolved (if I encounter unusual behavior through this I will report back for completeness).

                            Thanks Andreas

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