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

    Cannot access BaseDocument in Free() method

    SDK Help
    0
    19
    1.3k
    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 08/08/2013 at 00:26, xxxxxxxx wrote:

      Is the helper object an actual object (BaseObject derived) that is in the document? Then, yes, you need to add an undo for it explicitly.  Any association with the tag (such as a BaseLink) will not automatically restore it on an undo.

      doc->StartUndo();  
      // Add undo for both elements being deleted *before* deletion!  
      doc->AddUndo(UNDOTYPE_DELETE, myTag);  
      doc->AddUndo(UNDOTYPE_DELETE, myObject);  
      // Remove from document (required!)  
      myTag->Remove();  
      myObject->Remove();  
      // Free instances  
      BaseTag::Free(myTag);  
      BaseObject::Free(myObject);  
      doc->EndUndo();
      

      Your problem may be that since the tag needs to be removed from the document list before freeing it, it can not possibly be associated with the document any longer.  My suggestion is a class member to store the BaseDocument beforehand and use it in your Free() method

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

        On 08/08/2013 at 01:29, xxxxxxxx wrote:

        What's wrong with:

          
        void MyTag::Free(GeListNode* node)   
        {   
            BaseDocument* doc = node->GetDocument();   
        }   
        

        Steve

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

          On 08/08/2013 at 03:59, xxxxxxxx wrote:

          Originally posted by xxxxxxxx

          What's wrong with:

           
          void MyTag::Free(GeListNode* node)   
          {   
            BaseDocument* doc = node->GetDocument();   
          }   
          

          Steve

          What is wrong is that doc is NULL.
          That is the very reason I started this thread.

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

            On 08/08/2013 at 04:01, xxxxxxxx wrote:

            Originally posted by xxxxxxxx

            Your problem may be that..
            [..]

            myTag->Remove();  
            
            

            Hi Robert,
            my problem is just this: The doc is NULL, that is the reason I started this thread.
            I just cannot get hold of any BaseDocument in the Free() method.

            Apart from that, the tag is not removed programmatically. It is removed by the user, when the user deletes it. I suppose an undo here is inappropriate, and that the helper object has to be created again, if the user hits undo, in order to bring the tag back again.
            I see no way to bring back the helper object in the same operation when the user invokes undo.

            Edited:
            I can store the BaseDocument as a variable, at an earlier stage of the tag's life cycle, and it seems that this works ok. But I would rather get hold if it directly, in the Free() method.

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

              On 08/08/2013 at 04:28, xxxxxxxx wrote:

              Lo and behold - I found a solution!! 😄

              void MyTag::Free(GeListNode* node)
              {
              \> if(__HelperObject)
              \> 
              \> {
              \> 
              \>   	__BaseDocument->AddUndo(UNDOTYPE_DELETE, __HelperObject);
              \> 
              \>   	__HelperObject->Remove(); 
              \> 
              \> }
              }
              

              This works like magic! I have stored __BaseDocument at an earlier stage of the tag's life cycle, now it comes in handy, since node->GetDocument() returns NULL.
              And - even more interesting, it seems that the Free() method is already "inside" a doc->StartUnd() .. doc->EndUndo().

              So when the user manually deletes the tag, and then invokes undo, the tag, and the helper object, reappears!!
              So now all is just fine, only one issue remains - I cannot get hold of the BaseDocument inside the Free() method.

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

                On 08/08/2013 at 04:49, xxxxxxxx wrote:

                Just one question, why do you use double underscore (_ _) in variable names?
                In C++ this is reserved for implementation.  (like __declspec, __forceinline ...)

                http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier

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

                  On 08/08/2013 at 04:56, xxxxxxxx wrote:

                  Originally posted by xxxxxxxx

                  Just one question, why do you use double underscore (_ _) in variable names?

                  See my signature 😂

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

                    On 08/08/2013 at 04:58, xxxxxxxx wrote:

                    I'd chose a more elegant solution. It is quite possible that your Helper Object has been removed by
                    someone (user, module, whatever) and removing the Helper Object in that case can lead to a
                    crash.You can create an invisible tag sitting on the helper object. This tag should check if _your tag_
                    still exists, and if it does not, it can remove the object. (Choose to do this in a Message() calle since
                    scene modifications in TagData::Execute() or similar methods is not recommended by MAXON).

                    Best,
                    -Niklas

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

                      On 08/08/2013 at 05:10, xxxxxxxx wrote:

                      Originally posted by xxxxxxxx

                      What is wrong is that doc is NULL. That is the very reason I started this thread.

                      My point was why are you using such a convoluted method to get the document, but hey, just carry on.

                      To answer your question it appears that once Free() is called, the node has been removed from the document and therefore GetDocument() will always return null.

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

                        On 08/08/2013 at 05:31, xxxxxxxx wrote:

                        Originally posted by xxxxxxxx

                        My point was why are you using such a convoluted method to get the document, but hey, just carry on.

                        Sorry about that, did not mean to be rude. I overlooked the direct method, I am using your code now.

                        Originally posted by xxxxxxxx

                        To answer your question it appears that once Free() is called, the node has been removed from the document and therefore GetDocument() will always return null.

                        Ok, that seems to be correct! Nevertheless, storing the document as a variable seems to work just fine.

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

                          On 08/08/2013 at 05:33, xxxxxxxx wrote:

                          Originally posted by xxxxxxxx

                          I'd chose a more elegant solution. It is quite possible that your Helper Object has been removed by
                          someone (user, module, whatever) and removing the Helper Object in that case can lead to a
                          crash.You can create an invisible tag sitting on the helper object. This tag should check if _your tag_
                          still exists, and if it does not, it can remove the object. (Choose to do this in a Message() calle since
                          scene modifications in TagData::Execute() or similar methods is not recommended by MAXON).

                          Thanks Niklas! Yes, this is an elegant solution. In my case, however, the helper object is totally invisible. It does not appear in the work space, it is also hidden in the object browser. The user has no knowledge about its existence. So I can use the more simpler method in this case.

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

                            On 08/08/2013 at 05:56, xxxxxxxx wrote:

                            Originally posted by xxxxxxxx

                            Thanks Niklas! Yes, this is an elegant solution. In my case, however, the helper object is totally invisible. It does not appear in the work space, it is also hidden in the object browser. The user has no knowledge about its existence. So I can use the more simpler method in this case.

                            May I ask you why you even need this helper object then?

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

                              On 08/08/2013 at 06:45, xxxxxxxx wrote:

                              Originally posted by xxxxxxxx

                              May I ask you why you even need this helper object then?

                              The only solution I found so far, here is the problem:  
                              https://developers.maxon.net/forum/topic/7246/8326_constrain-rotation-to-object-with-skewed-axis&KW=

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

                                On 08/08/2013 at 07:14, xxxxxxxx wrote:

                                My suggestion is the best response.  If the helper object is not in the document, you need to invoke more in-depth methods (like CopyTo()) to ensure that the class membership is retained upon an undo.  That is, the object must be literally recognized during the free process and then reinstated during the undo process.  CopyTo() is there to transport non-C4D relevant data/memory/information between various processes such as copies for undo or render and such.  Think of it as memory you have allocated for the tag that must be reallocated when it is restored because it is not handled directly by C4D.  Some of the information must be retained in the BaseContainer/Description of the tag so that the helper object can be 'reconstructed' on a user undo process.

                                Welcome to the wonderful world of the C4D SDK API. 🙂

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

                                  On 08/08/2013 at 08:54, xxxxxxxx wrote:

                                  Ok Robert,
                                  but what is wrong with my approach, posted Today** at 1:28pm?
                                  It works just fine!

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

                                    On 08/08/2013 at 09:12, xxxxxxxx wrote:

                                    Times are displayed based on the timezone here.

                                    I already told you: It might crash in various situations. Unless you do not own an object, you should not store a pointer to it and assume it is valid anytime. And in this case, when the object is inserted in the document, you are not the owner of the object.

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

                                      On 08/08/2013 at 09:17, xxxxxxxx wrote:

                                      The code has been modified in the mean time. I keep the BaseDocument, and search for the object to be removed, by the name. By doing this, I am not storing a pointer to it.
                                      But I do store a pointer to the BaseDocument.

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

                                        On 08/08/2013 at 19:20, xxxxxxxx wrote:

                                        Simply create a LINK description in your tag and set it to the helper object.  If the object is deleted by the user, for instance, BaseLink knows about it.

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