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

    Creating Selection Tags

    Scheduled Pinned Locked Moved SDK Help
    11 Posts 0 Posters 857 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 14/01/2012 at 10:07, xxxxxxxx wrote:

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

      ---------
      Hey guys.
      There's all kinds of of good stuff in the archives on getting points and polygons from selection tags. But not one of them shows how to create the selection tag itself.

      I'm trying to use AutoAlloc. And I'm getting all kinds of crashing problems.

          BaseDocument *doc = GetActiveDocument();  
        BaseObject *obj = doc->GetActiveObject();    //Start out using BaseObject to grab the polygon object  
        PolygonObject *pobj = ToPoly(obj);          //Cast the BaseObject type to a PolygonObject type and assign it to a variable "pobj"  
        
        AutoAlloc<SelectionTag> st(Tpolygonselection); //Create a selection tag  
        
        /// Up to this point. Everything seems to work properly ///  
        
        pobj->InsertTag(st,NULL); // <--OUCH!! crashes C4D!
      

      I also tried to use MakeTag() and that crashes too.
      I'm missing something really simple. But I can't see it.
      How do I insert the tag on the object properly?

      -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 14/01/2012 at 13:11, xxxxxxxx wrote:

        After some hair pulling. I managed to figure it out using MakeTag() :

            BaseDocument *doc = GetActiveDocument();  
          BaseObject *obj = doc->GetActiveObject();    //Start out using BaseObject to grab the polygon object  
          if(!obj) return FALSE;  
          PolygonObject *pobj = ToPoly(obj);          //Cast the BaseObject type to a PolygonObject type and assign it to a variable "pobj"  
          if(!pobj) return FALSE;  
          
          LONG count = pobj->GetPolygonCount();       //Now you can use that variable as a polygon object, and all of the polygon class functions  
          
          BaseSelect *sel = pobj->GetPolygonS();      //Store the selected polygons  
            
          BaseTag *polytag = pobj->MakeTag(Tpolygonselection, NULL); //Create a new polygon selection tag      
          BaseTag *newpolytag = pobj->GetFirstTag();                 //Find the new tag and give it a new variable  
          if(newpolytag->GetType() &Tpolygonselection)  
          {  
            BaseSelect *select= static_cast<SelectionTag*>(newpolytag)->GetBaseSelect(); //Convert the BaseTag to a BaseSelect tag so we can edit it's contents   
            sel->CopyTo(select);       //Now that we have a BaseSelect for the tag. We can dump the selected polygons into that tag  
          }  
          
          pobj->Message(MSG_UPDATE); //Update any changes made to the object
        

        I would still really like to know how to do this same thing using AutoAlloc<> though.
        I need to understand why it crashes on me when I use InsertTag().
        Can anyone tell me how to use it properly?

        -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 14/01/2012 at 23:06, xxxxxxxx wrote:

          When the tag is inserted, ownership of the tag is passed to the object. AutoAlloc is attempting to free the tag when exiting the scope.

          Instead, you can use:

            
          SelectionTag* st = SelectionTag::Alloc(Tpolygonselection);   
          
          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 15/01/2012 at 08:04, xxxxxxxx wrote:

            Thanks for the help David.
            This is the second time I've run into this issue with AutoAlloc killing itself before I wanted it to.
            It seems to be very tricky to use properly in many cases. And there's not much documentation on it.

            I'd like to avoid using Alloc() as much as possible because of the manual freeing it requires me to do.
            But since AutoAlloc<> is so difficult to keep from killing itself prematurely. I might have to give up on it. And just handle all of the memory freeing myself.

            -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 15/01/2012 at 09:31, xxxxxxxx wrote:

              You can use AutoAlloc in the class declaration, so it will be freed automatically only when the class terminates. So if you were writing a particle modifier with falloff, for example, you can do this:

                
              class MyModifier: public ObjectData   
              {   
                   INSTANCEOF(MyModifier, ObjectData);   
              private:   
                   AutoAlloc<C4D_Falloff>falloff;   
                
              public:   
              // all the public functions etc.   
              };   
              

              Of course then the item will be a class-level variable, which might or might not be an issue.

              Steve

              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 15/01/2012 at 10:19, xxxxxxxx wrote:

                Thanks Steve.

                I think I've just got the wrong impression about AutoAlloc. And how/when to use it.
                The documentation is very limited about it. And leaves a lot of it's interpretation up to the developer.
                Which is a bad thing in my case. Because I'm still cutting my teeth, and I need to know EXACTLY how and why things work.
                When I'm forced to interpret things from the docs. That's where I make the most mistakes.

                Basically. I need to stop thinking of AutoAlloc<> as a shortcut to cheat memory handling for every situation. Because it's not really the best choice for every situation like I interpreted it from the docs.
                If I'm creating things with a command plugin for example. Then AutoAlloc<> won't work because it's tied to the life of my code...Not the life of the current document.

                -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 15/01/2012 at 12:56, xxxxxxxx wrote:

                  In this situation you don't use Free() because the object has ownership of the tag.

                  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 15/01/2012 at 14:35, xxxxxxxx wrote:

                    Ok. Thanks David.

                    As a test I tried using AutoAlloc<> in a tag situation where it should always be running and live. And not delete the selection tag. But even in this situation where I use a button click in a message method. It kills the tag right after it creates it. And never gets created. While using Alloc() works just fine:

                    Bool SimpleTag::Message(GeListNode *node, LONG type, void *data)  
                    {  
                      if (type == MSG_DESCRIPTION_CHECKDRAGANDDROP)  
                      {  
                        DescriptionCheckDragAndDrop *LNK = static_cast<DescriptionCheckDragAndDrop*>(data);  
                        switch (LNK->id[0].id)   
                        {  
                        case MY_LINK:  
                        case SPLINERAILOBJECT_SPLINE1:        
                        GePrint(LongToString(LNK->result));  
                      
                        return TRUE;  
                        }  
                      }  
                      
                      BaseDocument *doc = GetActiveDocument();  
                      BaseObject *obj = doc->GetActiveObject();    //Start out using BaseObject to grab the polygon object  
                      if(!obj) return FALSE;  
                      PolygonObject *pobj = ToPoly(obj);          //Cast the BaseObject type to a PolygonObject type and assign it to a variable "pobj"  
                      if(!pobj) return FALSE;  
                      
                      LONG count = pobj->GetPolygonCount();       //Now you can use that variable as a polygon object, and all of the polygon class functions  
                      
                      BaseSelect *sel = pobj->GetPolygonS();      //Store the selected polygons  
                      
                      //AutoAlloc<SelectionTag> st(Tpolygonselection);            //<---Does not work...It kills the tag  
                      SelectionTag* st = SelectionTag::Alloc(Tpolygonselection); //Works fine  
                      
                      switch (type)  
                        {          
                         case MSG_DESCRIPTION_COMMAND: // MSG_DESCRIPTION_COMMAND is send when button is clicked  
                          {              
                              DescriptionCommand *dc = (DescriptionCommand* )data; // data contains the description ID of the button             
                              LONG button = dc->id[0].id; // get the ID of the button  
                                            
                              switch (button) // check for different button IDs  
                              {  
                                  case BUTTON1:   
                                      pobj->InsertTag(st,NULL);  
                                          pobj->GetFirstTag();  //Find the new tag and give it a new variable  
                                          if(pobj->GetFirstTag()->GetType() &Tpolygonselection)  
                                           {  
                                            BaseSelect *select= static_cast<SelectionTag*>(pobj->GetFirstTag())->GetBaseSelect(); //Convert the BaseTag to a BaseSelect tag so we can edit it's contents   
                                            sel->CopyTo(select);       //Now that we have a BaseSelect for the tag. We can dump the selected polygons into that tag  
                                           }  
                                      break;  
                      
                                  case BUTTON2:  
                                      GePrint("Button2 was pushed");  
                                      break;  
                              }  
                          }  
                        }  
                      
                      
                      return TRUE;  
                    }
                    

                    I'm sure there's a good reason why AutoAlloc<> is not working in this example. But it just illustrates how confusing it is to use it.
                    You have to use in a very specific way. And if you don't. It's a monster that eats the villagers.😂

                    -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 15/01/2012 at 16:14, xxxxxxxx wrote:

                      Yes, that will never work. Think about what happens. Message() is called and you create a SelectionTag using AutoAlloc. The critical thing is this: once the object goes out of scope, it will automatically be freed. And it will go out of scope the moment Message() comes to an end.

                      It's really that simple. When using AutoAlloc just think about where you call it and when that function will terminate. If it terminates before you're ready to lose the object that was created, don't use AutoAlloc in that function. (Or do use it, but then use Release() to get a pointer to the object, and store that.)

                      In this case you can create a class-level variable and free it up when the tag terminates (e.g. is deleted by the user). You can either use AutoAlloc for that as I showed earlier or use Alloc then free it yourself in the tag's Free() function (note: that's a virtual function derived from NodeData, not the same as the Free() you would call to release an object you create).

                      Edit: in fact, thinking about it a little more, once you insert the tag into the document, it's my understanding that Cinema takes over the inserted object and will free it when the tag or object it's attached to is deleted. But I could be wrong about that.

                      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 15/01/2012 at 16:53, xxxxxxxx wrote:

                        Originally posted by xxxxxxxx

                        Edit: in fact, thinking about it a little more, once you insert the tag into the document, it's my understanding that Cinema takes over the inserted object and will free it when the tag or object it's attached to is deleted. But I could be wrong about that.

                        This is what I was saying above. When I use AutoAlloc or Alloc() with Free(), the tag disappears immediately after creation.

                        Using Alloc() only, the tag is retained with the debug console reporting no memory leaks.

                        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 15/01/2012 at 17:20, xxxxxxxx wrote:

                          Originally posted by xxxxxxxx

                          Message() is called and you create a SelectionTag using AutoAlloc. The critical thing is this: once the object goes out of scope, it will automatically be freed. And it will go out of scope the moment Message() comes to an end.

                          That's what I thought.
                          But because Message() executes continuously while C4D is running. I wasn't really 100% sure about how&when Message() went out of scope.
                          Your explanation helped to clear that up for me.
                          The class member variable work flow is something I'll try out in the future.

                          I think I have a better understanding of it now.
                          I'm sure I haven't conquered it completely, and I will probably wrestle with it again. But the help you guys have posted has helped clear it up a little bit. And given me some useful notes to use the next time I try to use AutoAlloc<> on something.

                          Thanks guys.🍺

                          -ScottA

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