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

    Populating InExclude description during Init()

    SDK Help
    0
    7
    656
    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 05/12/2014 at 22:01, xxxxxxxx wrote:

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

      ---------
      Hi guys,

      I'm trying to do this behavior for my object plugin's object creation:

      1. Select input objects in the Object Manager.
      2. Create new object (OBJ).
      3. place input objects in OBJ's InExcludeList (INEX).

        
      Bool OBJ::Init(GeListNode *node){  
        BaseContainer    *bc = ((BaseObject* )node)->GetDataInstance();  
        BaseDocument    *doc = GetActiveDocument();  
        if(!doc){  
            return TRUE;  
        }  
        
        AutoAlloc<AtomArray>    selection;  
        if(!selection){  
            return TRUE;  
        }  
        doc->GetActiveObjects(*selection, GETACTIVEOBJECTFLAGS_SELECTIONORDER);  
        if(selection->GetCount()){  
            Int64 i, k;  
            k = selection->GetCount();  
            InExcludeData *inex;  
            inex = (InExcludeData* )bc->GetCustomDataType(INEX, CUSTOMDATATYPE_INEXCLUDE_LIST);  
            for(i = 0; i < k; i++){  
                inex->InsertObject((BaseList2D* )selection->GetIndex(i), 0);  
            }  
        }  
        
        return TRUE;  
      }  
      

      The problem I'm having is that during the Init() call of OBJ, using (InExcludeData* )data->GetCustomDataType(INEX, CUSTOMDATATYPE_INEXCLUDE_LIST) returns nullptr.

      Is there a way to do this inside an object plugin's Init, or is my only option to create a command plugin that creates OBJ and populates INEX after?

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

        On 06/12/2014 at 07:25, xxxxxxxx wrote:

        I've found the Init() method to be very problematic for things like this.
        It seems to work best for setting things like variable values, file paths, and loading textures.
        So I only use it as a resource loader...never an object selector or creator.

        I haven't tried this. So it might not work.
        But it sounds a lot like the problem of trying to create things with a tag plugin.
        I've found that I have to check if a specific tag or object is selected inside of the Message() method. And then create the new tag or object in there.
        Using the Message() method this way is the only way I could find to create things without crashes.

        But I haven't tried this on an ObjectData plugin.
        So it might not work in your case.

        -ScottA

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

          On 06/12/2014 at 07:56, xxxxxxxx wrote:

          Init() is definitely not the place to do this.  Realize that it is called just after instantiation (constructor) and times thereafter.  Additionally, it is called when making copies (clones) of the object.  That is an operation where you really don't want to be selecting/creating objects because there may be no real document (it may be a copied document for render, for instance) or changing the document could lead to crashes.  There are plenty of valid message points to consider for doing this as Scott notes.

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

            On 06/12/2014 at 08:51, xxxxxxxx wrote:

            Thanks for the info guys.
            I guess to be safe I'll just create a command plugin/script to do this instead.

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

              On 07/12/2014 at 13:41, xxxxxxxx wrote:

              You may also need to initialize the InExclude before you start setting data in it.

              Try the following...

                
              bc->SetData(INEX, GeData(CUSTOMDATATYPE_INEXCLUDE_LIST, DEFAULTVALUE));     //This makes sure its initialized or clears it if there is already content in it. Do this in the Init method.   
                
              //Do the rest later on, since as described making selections during initialization is not a good idea.   
              InExcludeData *inex = nullptr;   
              inex = (InExcludeData* )bc->GetCustomDataType(INEX, CUSTOMDATATYPE_INEXCLUDE_LIST);   
              if (inex)   
              {   
              for(i = 0; i < k; i++)   
              {   
                 inex->InsertObject((BaseList2D* )selection->GetIndex(i), 0);   
              }   
              }   
              
              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 08/12/2014 at 04:11, xxxxxxxx wrote:

                Do it in the MSG_MENUPREPARE message.

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

                  On 08/12/2014 at 08:56, xxxxxxxx wrote:

                  Originally posted by xxxxxxxx

                  You may also need to initialize the InExclude before you start setting data in it.

                  Try the following...

                   
                  bc->SetData(INEX, GeData(CUSTOMDATATYPE_INEXCLUDE_LIST, DEFAULTVALUE));     //This makes sure its initialized or clears it if there is already content in it. Do this in the Init method.   
                   
                  //Do the rest later on, since as described making selections during initialization is not a good idea.   
                  InExcludeData *inex = nullptr;   
                  inex = (InExcludeData* )bc->GetCustomDataType(INEX, CUSTOMDATATYPE_INEXCLUDE_LIST);   
                  if (inex)   
                  {   
                  for(i = 0; i < k; i++)   
                  {   
                   inex->InsertObject((BaseList2D* )selection->GetIndex(i), 0);   
                  }   
                  }   
                  

                  Originally posted by xxxxxxxx

                  Do it in the MSG_MENUPREPARE message.

                  Just tried doing that and it seems to work now. I'll keep on testing to make sure I didn't mess anything else up.

                  This is what I placed inside Init:

                    
                  bc->SetData(INEX, GeData(CUSTOMDATATYPE_INEXCLUDE_LIST, DEFAULTVALUE));  
                  

                  And this is in Message:

                    
                    if(type == MSG_MENUPREPARE){  
                        BaseDocument *doc = ((BaseDocument* )t_data);  
                        if(!doc){  
                            GePrint("nodoc");//not sure if this section is needed, keeping it for now.  
                            return TRUE;  
                        }  
                        BaseContainer *bc = ((BaseObject* )node)->GetDataInstance();  
                        AutoAlloc<AtomArray>    selection;  
                        if(!selection){  
                            return TRUE;  
                        }  
                        doc->GetActiveObjects(*selection, GETACTIVEOBJECTFLAGS_SELECTIONORDER);  
                        if(selection->GetCount()){  
                            Int64 i, k;  
                            k = selection->GetCount();  
                            GePrint("selected: "+String().IntToString(k));  
                            InExcludeData *inex;  
                            inex = (InExcludeData* )bc->GetCustomDataType(INEX, CUSTOMDATATYPE_INEXCLUDE_LIST);  
                            for(i = 0; i < k; i++){  
                                inex->InsertObject((BaseList2D* )selection->GetIndex(i), 0);  
                            }  
                        }  
                    }  
                  

                  Thanks guys!

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