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

    Setting clone child as constrain target

    SDK Help
    0
    12
    973
    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 22/05/2017 at 04:24, xxxxxxxx wrote:

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

      ---------
      I have a Cloner with a Sphere as child and count set to 3._<_o:_<_o:p_>_o:p>
      Now I want to access the second cloner object and set it as target in the Constrain-Clamp Tag. 
      So, I do a CurrentStateToObject and get the second (child) _<_o:_<_o:p_>_
      Note: I do not insert the new object, so it is just_<_o:_<_o:p_>_ory(?).
      Then I create the Constrain tag and put this second (child) object_<_o:_<_o:p_>_ Target field.
      Here the high level code.

        
      ModelingCommandData cd;  
      cd.doc = GetActiveDocument();  
      cd.op = obj;  
      SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, cd);
      cstObject = (BaseObject* )cd.result->GetIndex(0);
        
      //get object
      BaseObject* ob = cstObject->GetDown();  
      ob = ob->GetNext();                          
        
      //set target in constrain - clamp tag  
      res = constraintTag->SetParameter(50001, ob, DESCFLAGS_SET_0);  
       
      

      I can see that I get the correct object (sphere 1), but the Constrain – Clamp Tag field stays emp_<_o:_<_o:p_>_
      In python this is working and the field is filled with: Cloner / Sphere 1 / Sphere 1
      Any hints?
      -Pim

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

        On 22/05/2017 at 08:15, xxxxxxxx wrote:

        IMHO. Using SMC like this is rather ugly. And asking for crashes if it's called too many times, too quickly.
        If you're not married to using a constraint tag. I can show you how to constrain an object to a specific clone by directly getting it's position data from the Cloner Object. Without using a constraint tag and doing that nasty SMC stuff.

        -ScottA

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

          On 22/05/2017 at 08:42, xxxxxxxx wrote:

          The thing is that I do not know which specific clone.

          The user selects an object, which can be a clone.
          After that, I get the selected object using PickObject().

          Everything is ok, if the selected object is not a clone.

          -Pim

          Note. I would love to see your suggested solution.

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

            On 22/05/2017 at 08:47, xxxxxxxx wrote:

            Could it be that after I do the MCOMMAND_CURRENTSTATETOOBJECT, the object is not yet in the hierarchy, only in memory. And thus I can not us it as a constrain?

            -Pim

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

              On 22/05/2017 at 08:50, xxxxxxxx wrote:

              NP.
              This might not solve your problem. But it might be useful for some other project.

              //This will lock a Null object to the second clone in a ClonerObject. Similar to using a constraint tag  
                
              #include "c4d_baseeffectordata.h"  
                
                
                BaseObject *target = doc->SearchObject("Null");  
                if (!target) return false;  
                Matrix targetMtx = target->GetMg();  
                
                //The cloner object  
                BaseObject *clonerObj = doc->SearchObject("Cloner");  
                if (!clonerObj || clonerObj->GetType() != 1018544) return false;  
                
                //Get the hidden MoData tag that is on the cloner object  
                BaseTag *moTag = clonerObj->GetTag(ID_MOTAGDATA);  
                if (!moTag) return false;  
                
                //Retrieve the MoData  
                GetMoDataMessage msg_data;  
                if (!moTag->Message(MSG_GET_MODATA, &msg_data)) return false;  
                
                if (msg_data.modata)  
                {  
                    //Get the matrix data for the clones  
                    MoData *md = msg_data.modata;  
                    MDArray<Matrix>mtx = md->GetMatrixArray(MODATA_MATRIX);  
                      
                    //The Global Position of the second clone  
                    Vector clonePos = mtx[2].off * clonerObj->GetMg();  
                
                    //Lock the Null object to the position of the second clone  
                    targetMtx.off = clonePos;          
                    target->SetMg(targetMtx);          
                }
              

              -ScottA

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

                On 22/05/2017 at 09:11, xxxxxxxx wrote:

                Thanks for the code. I am certain it will be helpful in other plugins.
                Again something for the "big book with solutions".

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

                  On 22/05/2017 at 09:16, xxxxxxxx wrote:

                  Originally posted by xxxxxxxx

                  Could it be that after I do the MCOMMAND_CURRENTSTATETOOBJECT, the object is not yet in the hierarchy, only in memory. And thus I can not us it as a constrain?

                  It has indeed something to do with issue.

                  If I, for test purposes, insert the resulting object (of the CSTO), then it works.

                  GetActiveDocument()->InsertObject(cstObject, nullptr, nullptr);  
                  EventAdd();
                  

                  So the question is, how to use a "virtual object(?)" - an object that is only in memory - as a target?

                  -Pim

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

                    On 22/05/2017 at 09:32, xxxxxxxx wrote:

                    Originally posted by xxxxxxxx

                    Originally posted by xxxxxxxx

                    Could it be that after I do the MCOMMAND_CURRENTSTATETOOBJECT, the object is not yet in the hierarchy, only in memory. And thus I can not us it as a constrain?

                    It has indeed something to do with issue.

                    If I, for test purposes, insert the resulting object (of the CSTO), then it works.

                    GetActiveDocument()->InsertObject(cstObject, nullptr, nullptr);  
                    EventAdd();
                    

                    So the question is, how to use a "virtual object(?)" - an object that is only in memory - as a target?

                    Can I do something with the cache of the object?

                    -Pim

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

                      On 23/05/2017 at 09:47, xxxxxxxx wrote:

                      Hi Pim,

                      the problem is indeed the clone not being part of the document. In the constraint tag the reference to the object is stored as a BaseLink and such gets resolved in the context of a document. And here we run into issues with clones from a Cloner. That's unfortunately not the usual use-case of the constraint tag. And I'm not sure yet, if we have a workaround in this case. Probably "easiest" would be to create your own Constraint TagData plugin, which takes care of this special situation.

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

                        On 25/05/2017 at 01:01, xxxxxxxx wrote:

                        Hi Andreas,

                        Thanks for the reply. I solved the issue using the cache.
                        Here the test code I used.

                        			obj = GetActiveDocument()->SearchObject("Object with constraint tag");
                        			constraintTag = obj->GetTag(1019364);				//Constraint Tag = 1019364
                        			clonerObj = GetActiveDocument()->SearchObject("Cloner object");
                          
                        			clone = clonerObj->GetCache();
                        			// get second clone
                        			if (clone) {
                        				   clone = clone->GetDown();
                        				   clone = clone->GetNext();
                          
                           //set target
                        				   res = constraintTag->SetParameter(ID_CA_CONSTRAINT_TAG_CLAMP, TRUE, DESCFLAGS_SET_0);
                        				   res = constraintTag->SetParameter(50001, clone, DESCFLAGS_SET_0);			
                        			}
                        

                        -Pim

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

                          On 29/05/2017 at 02:42, xxxxxxxx wrote:

                          Hi Pim,

                          well, as I said before, you are probably leaving the tested areas by linking a cache object into the Constraint tag. But if it works for you, fine. One thing we didn't talk about so far, is the context where you try to do this? Is it in a NodeData plugin or rather CommandData?

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

                            On 30/05/2017 at 03:58, xxxxxxxx wrote:

                            Yes, I place a cache object in the target field of the constraint.
                            The setting of the constraint is done in a CommandData plugin.

                            -Pim

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