Programatically Freeze All



  • On 31/05/2013 at 02:52, xxxxxxxx wrote:

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

    ---------
    How do I do this in C++?

    I want to achieve exactly the same as I do when pressing this button.
    I have spent a couple of hours reading me up on the SDK and I understand the difference between global / local coordinates on one side, and abs/rel coordinates on the other side.
    But still I am struggling with this.

    If anyone could help me, perhaps provide some code, I would be very thankful!



  • On 31/05/2013 at 03:34, xxxxxxxx wrote:

    CallButton(). You can look up the id of the button in the Obase description.

    -Nik



  • On 31/05/2013 at 03:44, xxxxxxxx wrote:

    Ok, Niklas, but that won't help me in my case.
    I want to Freeze any given object, or several objects in one operation, without selecting anyone of them  first.
    So I need to use the methods SetFrozen(), GetAbs GetRel and so on. But I have not figered out how to do it the right way, so far. 
    The image, the picture I show, is only there to explain what I want, in principle.



  • On 31/05/2013 at 04:18, xxxxxxxx wrote:

    Read CallButton() it does include a BaseList2D as the target parameter. You do not have
    to be the object active in the AM. But generally speaking you want might want to read 
    about freezing objects in the SDK and writing the values yourself. Search for _Freeze  _
    Transformations in the  SDK.



  • On 31/05/2013 at 05:18, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    But generally speaking you want might want to read 
    about freezing objects in the SDK and writing the values yourself. Search for _Freeze  _
    Transformations in the  SDK.

    As I wrote in my initial post, that is exactly what I already have done. The reason I post here, is that I still do not get it. Having read all these docs, I still do not know what code to write, that will do the same as C4D does when I push the button. In the SDK, there is no code example (as far as I can tell) that does just that. Yes, the   _Freeze  _ Transformations page(s) has lots of info. Two pictures and some kind of code examples too. But not the actual code that will freeze an object, based on its current position.

    If anyone has an example on how to freeze an object, so that Reset PSR can be used on this object, it is very much appreciated! I can find out about it, by experimenting, I am sure. But I need more time it seems..



  • On 31/05/2013 at 06:28, xxxxxxxx wrote:

    not sure what your problem is, here a simple example on how to freeze an object in python
    and applying a relative offset vector to the object position on top of that.

    import c4d
    from c4d import utils
    #Welcome to the world of Python
      
    def main() :
        OffsetFreeze(op, c4d.Vector(0,100,0))
        c4d.EventAdd()
      
    def OffsetFreeze(op, offset) :
        # freeze current abs
        op.SetFrozenPos(op.GetAbsPos())
        op.SetFrozenScale(op.GetAbsScale())
        op.SetFrozenRot(op.GetAbsRot())
        # zero out the rel matrix and add the offset
        op.SetRelPos  (offset)
        op.SetRelScale(c4d.Vector(1))
        op.SetRelRot  (c4d.Vector())
      
    if __name__=='__main__':
        main()
    

    its a script, simply paste it in the script manager, select an object and hit it multiple times,
    while watching the coords manager.



  • On 31/05/2013 at 06:37, xxxxxxxx wrote:

    Hi Little Devil, my problem is my head, that sometimes does not work.. I have been experimenting since my last post, and I think I understand it now. Thanks for the Python code! I will look into it, and come back with C++ code that works ;)



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

    C++ does not have a CallButton() function. That's for Python only.
    To execute buttons in C++. You have to use a DescriptionCommmand.

    Here's how to execute the various Freeze buttons in C++:

    //This code executes the Freeze options on an object  
      
    Bool SimplePlugin::Execute(BaseDocument *doc)  
    {  
      
      BaseObject *obj = doc->GetActiveObject();  
      //obj->SetFrozenPos(Vector(0,0,0));                  //Sets the freeze value fields if desired  
      
      DescriptionCommand dc;  
      dc.id = DescID(DescLevel(ID_BASEOBJECT_FREEZE));          //Executes the Freeze All button  
      //dc.id = DescID(DescLevel(ID_BASEOBJECT_FREEZE_P));      //Executes the Freeze P button  
      //dc.id = DescID(DescLevel(ID_BASEOBJECT_FREEZE_S));      //Executes the Freeze S button  
      //dc.id = DescID(DescLevel(ID_BASEOBJECT_FREEZE_R));      //Executes the Freeze R button  
      //dc.id = DescID(DescLevel(ID_BASEOBJECT_FROZEN_RESET));  //Executes the Unfreeze All button  
      obj->Message(MSG_DESCRIPTION_COMMAND, &dc);  
      
      obj->Message(MSG_UPDATE);  
      EventAdd();          
       
      return TRUE;  
    }
    

    It's not shown in the docs.
    The only reason I know this code is because I've asked lots of questions about how to execute buttons. And Matthias (MAXON) provided me with the code on how to execute them.

    -ScottA



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

    Ok guys, thanks! I am still experimenting. It was maybe unfortunate that I submitted the screen-shot. It is not about pushing the button. It is about programatically (using methods) doing the same as the button does.  I will come back when I have found out how to do it.



  • On 31/05/2013 at 09:00, xxxxxxxx wrote:

    @ScottA: Oh thanks for the clarification! I didn't know that, since I never needed to call a button from
    C++ (actually from Python neither).

    -Nik



  • On 31/05/2013 at 16:52, xxxxxxxx wrote:

    Hi everyone, here is my code. I am sorry about creating so much confusion, as the solution is very simple. It is almost like the Python code littledevil quoted, but I had to find out myself how things work, to be sure.
    For anyone interested, here is the code that (so far) works for me. And the solution I also was looking for, although I did a poor job describing what I was after..
    Hope this will be useful to those who need to call Freeze or PSR programatically.

        void FreezeObject(BaseObject* object)
        {
            object->SetFrozenPos(object->GetAbsPos());
            object->SetFrozenScale(object->GetAbsScale());
            object->SetFrozenRot(object->GetAbsRot());
            ResetPSR(object);
        }
        
        void ResetPSR(BaseObject* object)
        {
            object->SetRelPos(Vector(0));
            object->SetRelScale(Vector(1));
            object->SetRelRot(Vector(0));
        }
    

Log in to reply