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

    Trouble creating an xpresso node

    Scheduled Pinned Locked Moved SDK Help
    9 Posts 0 Posters 831 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

      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

      On 23/05/2011 at 16:03, xxxxxxxx wrote:

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

      ---------
      Hi,

      I'm trying to convert this python code to C++:

      import c4d  
      from c4d import gui  
        
      def main() :  
        nm = doc.GetActiveTag().GetNodeMaster() #Get the node master of selected xpresso tag  
        node = nm.CreateNode(nm.GetRoot(), c4d.ID_OPERATOR_OBJECT,insert=None, x=200, y=200) #Create the object's node  
          
        node.AddPort(c4d.GV_PORT_OUTPUT, c4d.ID_BASEOBJECT_POSITION) #add a position output port to the object node  
        print node.GetOperatorContainer()[c4d.GV_OBJECT_OBJECT_ID].GetName() #print name    
        c4d.EventAdd()    
        
      if __name__=='__main__':  
        main()
      

      But I'm having lots of trouble figuring out how to properly use the GvNode and GvNodeMaster types:

      Bool SimplePlugin::Execute(BaseDocument *doc)  
      {   
        
        BaseObject *obj = doc->GetFirstObject();  
        if(!obj) return true;  
        BaseTag *xtag = obj->MakeTag(Texpresso, NULL);  
        xtag->SetBit(BIT_ACTIVE);  
        
      ///////////// Everything is working fine up to here /////////////////  
        
        GvNodeMaster *nm = doc->GetActiveTag()->GetNodeMaster(); //Error: BaseTag has no member GetnodeMaster  
        GvNode *node = nm->CreateNode(nm->GetRoot(), ID_OPERATOR_OBJECT, insert=None, x=200, y=200); //<--wrong    
        node->AddPort(GV_PORT_OUTPUT, ID_BASEOBJECT_POSITION); //<--wrong    
            
        EventAdd();    
        
      return true;  
      }
      

      Can anyone help?

      -ScottA

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

        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

        On 24/05/2011 at 02:22, xxxxxxxx wrote:

        You have to cast the BaseTag into an XPressoTag.

        Something like this:

        GvNodeMaster *nm = ((XPressoTag* )doc->GetActiveTag())->GetNodeMaster();
        

        cheers,
        Matthias

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

          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

          On 24/05/2011 at 08:00, xxxxxxxx wrote:

          Thanks.
          Here's the code I came up with that creates an xpresso tag with a node inside of it:

          #include "c4d_graphview.h"  
            
          Bool SimplePlugin::Execute(BaseDocument *doc)  
          {   
            BaseObject *obj = doc->GetFirstObject();  
            if(!obj) return true;  
            BaseTag *xtag = obj->MakeTag(Texpresso, NULL);  
            xtag->SetBit(BIT_ACTIVE);  
            
            GvNodeMaster *nm = ((XPressoTag* )doc->GetActiveTag())->GetNodeMaster();      
            GvNode *node = nm->CreateNode(nm->GetRoot(), ID_OPERATOR_OBJECT, NULL, 200, 200);      
            node->AddPort(GV_PORT_OUTPUT, GV_PORT_FLAG_IS_VISIBLE);         
            EventAdd();    
            
          return true;  
          }
          

          However,
          I could not make this line of code work:

          node->AddPort(GV_PORT_OUTPUT, ID_BASEOBJECT_POSITION); // <---ID_BASEOBJECT_POSITION is undefined
          

          I assume the ID's have to be available somewhere. Because it works under python.
          But as usual. Doing a search for "ID_BASEOBJECT_POSITION" results in zilch. 😠
          And without them I can't set the ports to anything. Do you know where they are?

          -ScottA

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

            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

            On 24/05/2011 at 08:59, xxxxxxxx wrote:

            Since R12 Cinema supports Freeze transformation that's why ID_BASEOBJECT_POSITION has been renamed to ID_BASEOBJECT_REL_POSITION.

            In doubt check the IDs by dragging the description elements in question into the console or script editor.

            cheers,
            Matthias

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

              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

              On 24/05/2011 at 09:43, xxxxxxxx wrote:

              Originally posted by xxxxxxxx

              check the IDs by dragging the description elements in question into the console or script editor.

              When I did that. The console told me this: [OK]ID_BASEOBJECT_POSITION
              I'm not sure how that's going to help me out. Because it's not OK to use that ID in C++ .
              Maybe I'm misunderstanding how to use it?

              ID_BASEOBJECT_REL_POSITION works. But where the heck are these descriptions stored?
              I still can't find it. And I'll need the rest of them in order to create other kinds of ports.

              I also noticed that using this method. The port does not get added to my xpresso node like it does in python.
              So can I assume that this is only adding the port in memory? And it needs to somehow be inserted into the node?

              Sorry for all the questions.
              Usually python and C++ are fairly similar and I can usually figure out how to convert between the two.
              But in this case they seem to do things very differently.

              -ScottA

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

                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                On 24/05/2011 at 11:31, xxxxxxxx wrote:

                You can find some others in the resource/res/description/obase.h|.res files.  Remember that not everything is defined in the _api folder.  A lot is defined in the modules and res folders in the resource.  Some even in the modules folder outside of the resource folder!

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

                  THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                  On 24/05/2011 at 11:57, xxxxxxxx wrote:

                  Thanks Robert.
                  I generally do check through all of the folders in the maxon folder. Not just in the API.
                  The problem is.. There's a ton of them. And if I looked in each and every folder it would take several hours.
                  I tried using Agent Ransack. But that doesn't seem to find them any better than windows built-in search.
                  Every time I need to look up the location of an ID. It's a painful experience.
                  If there was one thing I could change. It would be to organize the ID's in one replace, where they can easily be found with a search. Instead of scatter throughout tons of files and folders.
                  OOP is supposed to help us be organized and work faster with large projects...Not get in our way. 😉

                  Anyway.
                  I think I'm starting to see how this node ID stuff works... I think.
                  When we create an xpresso node. It has a certain type like: ID_OPERATOR_OBJECT. So to find the port ID's available to use on it. We can look up the BaseObject class and the ID's in there will probably work in that xpresso node.
                  That's my theory anyway.😉

                  Now I just need to figure out how to insert (Alloc()?)  new ports into the new xpresso node.

                  -ScottA

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

                    THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                    On 24/05/2011 at 12:07, xxxxxxxx wrote:

                    Agent Ransack is a great file search application.  Much more reliable than the Windows Explorer search.  That way I don't have to hunt it down, just search and destroy. 🙂

                    Here is a piece of code that Mikael Sterner gave me a few years back.  The AddPort() part seems to have worked (but cannot find the experimental project in which I was working with the Xpresso nodes) :

                        
                        
                        #include "c4d_graphview.h"  
                        #include "c4d_operatorplugin.h"  
                        #include "......\resource\modules\gv\expressiontag\res\description\gvobject.h"  
                        #define GvCall(op,fnc) (((GvOperatorData* )op)->*((OPERATORPLUGIN* )C4DOS.Bl->RetrieveTableX((NodeData* )op,1))->fnc)
                        
                        
                        Bool MenuTest::Execute(BaseDocument *doc)  
                        {   
                          BaseObject* cube = doc->GetFirstObject();  
                          BaseObject* sphere = cube->GetNext();  
                            
                          DescID cubeid = DescID(DescLevel(ID_BASEOBJECT_POSITION), DescLevel(VECTOR_X));  
                          DescID sphereid = DescID(DescLevel(ID_BASEOBJECT_POSITION), DescLevel(VECTOR_Y));  
                            
                          XPressoTag* x = static_cast<XPressoTag*>(sphere->GetTag(Texpresso, 0));  
                          if (!x) x = static_cast<XPressoTag*>(sphere->MakeTag(Texpresso, NULL));  
                            
                          GvNodeMaster* m = x->GetNodeMaster();  
                            
                          GvNode* n1 = m->CreateNode(m->GetRoot(), ID_OPERATOR_OBJECT, NULL, 8, 8);  
                          n1->OperatorSetData(GV_ATOM, cube, GV_OP_DROP_IN_BODY);  
                          GvOperatorData* op1 = n1->GetOperatorData();    
                          LONG s1 = GvCall(op1, GetMainID)(n1, GV_PORT_OUTPUT, cubeid);  
                          GvPort* p1 = n1->AddPort(GV_PORT_OUTPUT, s1, GV_PORT_FLAG_IS_VISIBLE, TRUE);  
                            
                          GvNode* n2 = m->CreateNode(m->GetRoot(), ID_OPERATOR_OBJECT, NULL, 208, 8);  
                          n2->OperatorSetData(GV_ATOM, sphere, GV_OP_DROP_IN_BODY);  
                          GvOperatorData* op2 = n2->GetOperatorData();    
                          LONG s2 = GvCall(op2, GetMainID)(n2, GV_PORT_INPUT, sphereid);  
                          GvPort* p2 = n2->AddPort(GV_PORT_INPUT, s2, GV_PORT_FLAG_IS_VISIBLE, TRUE);  
                            
                          if (p1 && p2)  
                          {  
                          GvNode* n1u = NULL;  
                          GvNode* n2u = NULL;  
                          GvPort* p1u = NULL;  
                          GvPort* p2u = NULL;  
                          if (m->IsConnectionValid(n1, p1, n2, p2, n1u, p1u, n2u, p2u))  
                          {  
                            n2->AddConnection(n1u, p1u, n2u, p2u);  
                          }  
                          }  
                            
                          EventAdd();  
                            
                          return TRUE;  
                        }
                    
                    1 Reply Last reply Reply Quote 0
                    • H Offline
                      Helper
                      last edited by

                      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                      On 24/05/2011 at 12:57, xxxxxxxx wrote:

                      Thanks.
                      That helps me out a lot!

                      -ScottA

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