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

    PLA tracks?

    Scheduled Pinned Locked Moved SDK Help
    4 Posts 0 Posters 424 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 15/01/2011 at 10:50, xxxxxxxx wrote:

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

      ---------
      Howdy,

      How do you allocate a PLA track and set keys?

      I searched the forum and found this thread:
      https://developers.maxon.net/forum/topic/2224/1577_pla-animation-in-c&KW=PLAKey

      .... but the code presented there is not working.

      First of all, I can not find "ID_ANIM_PLA" anywhere in any header files on my machine, so I created a test to find out what the ID was of a PLA track to be sure it was the same as stated in that thread:

      BaseObject *op = doc->GetActiveObject();
      CTrack *trk = op->GetFirstCTrack();
      if(trk)
      {
      	DescID dscID = trk->GetDescriptionID();
      	GePrint(DescIDToString(dscID));
      }
      

      ... which confirmed the ID number was the same.

      Then I tried to allocate a PLA for a polygon object like this:

      #define ID_PLA_TRACK            100004812
        
      DescID trkID = DescID(ID_PLA_TRACK,ID_PLA_TRACK,0);
      								
      CTrack *track = op->FindCTrack(trkID);
      if(!track)
      {
          track = CTrack::Alloc(op,trkID);
          if(track) op->InsertTrackSorted(track);
          else GePrint("Could not allocate PLA track for "+op->GetName());
      }
      

      ... and it always fails.

      Adios,
      Cactus Dan

      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/2011 at 12:37, xxxxxxxx wrote:

        Well here is the contents of ckpla.h   maybe they changed the names of those constants since then.  🙂

          
        #ifndef _CKPLA_H_  
        #define _CKPLA_H_  
          
        enum  
        {  
          CK_PLA_BIAS  = 10001, // real  
          CK_PLA_CUBIC = 10002, // bool  
          CK_PLA_DATA  = 10003,  
          
          CK_PLA_DUMMY  
        };  
          
        #endif  
        

        EDIT:   Scratch that..  The second two are part of ckpla.h I can't find ID_ANIM_PLA either   lol.

        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/2011 at 12:48, xxxxxxxx wrote:

          #ifdef    C4D_R10  
            #ifdef    XCODE  
                enum  
                {  
                    ID_ANIM_PLA            =    100004812L  
                };  
                #include "ckpla.h"  
            #else  
                #include "newman\res\c4d_symbols.h"  
                #include "newman\res\description\ckpla.h"  
                #ifdef    C4D_R105  
                    #define    ID_ANIM_PLA        CTpla  
                #endif  
            #endif  
          #endif  
            
          // Fix Animation onto Polygon object as PLA track  
          //*---------------------------------------------------------------------------*  
          Bool IPPFix::FixPolygonAnimation(PointObject* orig, PointObject* root, LONG* partial, LONG elements)  
          //*---------------------------------------------------------------------------*  
          {  
            // Get Destination point array  
            Vector*            dpoint =    root->GetPointW();  
            if (!dpoint)    return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_GENERAL_TEXT), "FixPolygonAnimation.root", "Has No Points");  
            
            // Check for Spla track, create if none  
            DescID            descID =    DescLevel(ID_ANIM_PLA,ID_ANIM_PLA,0L);  
            CTrack*            track =        root->FindCTrack(descID);  
            if (!track)  
            {  
                track =        CTrack::Alloc(root, descID);  
                if (!track)    return ErrorException::OOMThrow(EE_DIALOG, GeLoadString(IPPERR_MEMORY_TEXT), "FixPolygonAnimation.track");  
                root->InsertTrackSorted(track);  
                doc->AddUndo(UNDOTYPE_NEW, track);  
            }  
            BaseTime        stime =        doc->GetMinTime();  
            BaseTime        etime =        doc->GetMaxTime();  
            CCurve*            seq =        track->GetCurve();  
            if (!seq)    return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MEMORY_TEXT), "FixPolygonAnimation.seq");  
            seq->FlushKeys();  
            
            // Sample Animation at AnimSample intervals  
            ModelingCommandData        mcd;  
            mcd.doc =                doc;  
            mcd.op =                orig;  
            BaseContainer            mbc;  
            mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_INHERITANCE,        TRUE);  
            mbc.SetBool(MDATA_CURRENTSTATETOOBJECT_KEEPANIMATION,    FALSE);  
            mcd.bc =                &mbc;  
            mcd.flags =                MODELINGCOMMANDFLAGS_0;  
            
            BaseObject*        csto =            NULL;  
            PointObject*    defd =            NULL;  
            CKey*            key =            NULL;  
            const Vector*    spoint =        NULL;  
            Vector*            points =        NULL;  
            Vector*            lpoints =        NULL;  
            DescID            biasDID =        DescLevel(CK_PLA_BIAS, DTYPE_REAL,0L);  
            DescID            cubicDID =        DescLevel(CK_PLA_CUBIC, DTYPE_BOOL,0L);  
            LONG            pointCount =    root->GetPointCount();  
            LONG            pointSize =        pointCount*sizeof(Vector);  
            Real            fps =            doc->GetFps();  
            LONG            startf =        stime.GetFrame(fps);  
            LONG            endf =            etime.GetFrame(fps);  
            StatusSetText("Fixing Animation for "+orig->GetName());  
            for (; startf <= endf; startf += AnimSample)  
            {  
                stime =            BaseTime::BaseTime(startf, fps);  
                // - Animate Document to change the points of orig  
                doc->SetTime(stime);  
          #ifdef    C4D_R12  
                doc->ExecutePasses(NULL, TRUE, TRUE, TRUE, BUILDFLAGS_0);  
          #else  
                doc->AnimateDocument(NULL, TRUE, TRUE);  
          #endif  
                EventAdd();  
            
                // Current State to Object  
                if (!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, mcd))    return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MODELINGCOMMAND_TEXT), "FixPolygonAnimation");  
                csto =        static_cast<BaseObject*>(mcd.result->GetIndex(0));  
                AtomArray::Free(mcd.result);  
                if (!csto)    return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MODELINGCOMMAND_TEXT), "FixPolygonAnimation.csto");  
                if (csto->IsInstanceOf(Onull))  
                {  
                    defd =        ToPoint(csto->GetDown());  
                    if (!defd)    return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MODELINGCOMMAND_TEXT), "FixPolygonAnimation.defd");  
                }  
                else    defd =    ToPoint(csto);  
            
                // - Add KeyFrame  
                key =            seq->AddKey(stime);  
                if (!key)  
                {  
                    BaseObject::Free(csto);  
                    return ErrorException::OOMThrow(EE_DIALOG, GeLoadString(IPPERR_MEMORY_TEXT), "FixPolygonAnimation.key");  
                }  
                doc->AddUndo(UNDOTYPE_NEW, key);  
            
                // - Add PLA data  
                // + R10  
                spoint =        defd->GetPointR();  
                if (!spoint)  
                {  
                    GePrint("Source Obj has no Points");  
                    BaseObject::Free(csto);  
                    break;  
                }  
                // Apply parent animation to points  
                points =        defd->GetPointW();  
                lpoints =        points+pointCount;  
                for (; points != lpoints; ++points)    (*points) *= orig->GetMg();  
            
          #ifdef    OS64  
                CopyMem(spoint, dpoint, static_cast<VLONG>(pointSize));  
          #else  
                CopyMem(spoint, dpoint, pointSize);  
          #endif  
                // - R10  
                if (!track->FillKey(doc,root,key))  
                {  
                    BaseObject::Free(csto);  
                    return ErrorException::Throw(EE_DIALOG, "FixPolygonAnimation.FillKey failed");  
                }  
                // Do these AFTER FillKey()!  
                key->SetParameter(biasDID, GeData(AnimBias), DESCFLAGS_SET_0);  
                key->SetParameter(cubicDID, GeData(AnimSmooth), DESCFLAGS_SET_0);  
            
                BaseObject::Free(csto);  
            
                // Update progress bar on each frame  
                StatusSetBar(((*partial)*100L)/elements);  
                ++(*partial);  
            }  
            // Ended at last frame - done  
            if (startf == endf)  
            {  
                // Clear global matrix  
                root->SetMg(unitMatrix);  
                return TRUE;  
            }  
            
            // Cap last frame with PLA key  
            stime =            BaseTime::BaseTime(startf, fps);  
            // - Animate Document to change the points of orig  
            doc->SetTime(stime);  
          #ifdef    C4D_R12  
            doc->ExecutePasses(NULL, TRUE, TRUE, TRUE, BUILDFLAGS_0);  
          #else  
            doc->AnimateDocument(NULL, TRUE, TRUE);  
          #endif  
            EventAdd();  
            
            if (!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, mcd))    return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MODELINGCOMMAND_TEXT), "FixPolygonAnimation");  
            csto =        static_cast<BaseObject*>(mcd.result->GetIndex(0L));  
            AtomArray::Free(mcd.result);  
            if (!csto)    return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MODELINGCOMMAND_TEXT), "FixPolygonAnimation.csto");  
            if (csto->IsInstanceOf(Onull))  
            {  
                defd =        ToPoint(csto->GetDown());  
                if (!defd)    return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MODELINGCOMMAND_TEXT), "FixPolygonAnimation.defd");  
            }  
            else    defd =    ToPoint(csto);  
            
            // - Add KeyFrame  
            key =            seq->AddKey(stime);  
            if (!key)  
            {  
                BaseObject::Free(csto);  
                return ErrorException::OOMThrow(EE_DIALOG, GeLoadString(IPPERR_MEMORY_TEXT), "FixPolygonAnimation.key");  
            }  
            doc->AddUndo(UNDOTYPE_NEW, key);  
            
            // - Add PLA data  
            // + R10  
            spoint =        defd->GetPointR();  
            if (!spoint)  
            {  
                GePrint("Source Obj has no Points");  
                BaseObject::Free(csto);  
                return TRUE;  
            }  
            // Apply parent animation to points  
            points =        defd->GetPointW();  
            lpoints =        points+pointCount;  
            for (; points != lpoints; ++points)    (*points) *= orig->GetMg();  
            
          #ifdef    OS64  
            CopyMem(spoint, dpoint, static_cast<VLONG>(pointSize));  
          #else  
            CopyMem(spoint, dpoint, pointSize);  
          #endif  
            // - R10  
            if (!track->FillKey(doc,root,key))  
            {  
                BaseObject::Free(csto);  
                return ErrorException::Throw(EE_DIALOG, "FixPolygonAnimation.FillKey failed");  
            }  
            // Do these AFTER FillKey()!  
            key->SetParameter(biasDID, GeData(AnimBias), DESCFLAGS_SET_0);  
            key->SetParameter(cubicDID, GeData(AnimSmooth), DESCFLAGS_SET_0);  
            
            BaseObject::Free(csto);  
            
            // Clear global matrix  
            root->SetMg(unitMatrix);  
            
            return TRUE;  
          }  
          
          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/2011 at 15:12, xxxxxxxx wrote:

            Howdy,

            Actually, I came up with something that works, and is easier to implement:

                AutoAlloc<AliasTrans> trans;
            #if API_VERSION < 12000
                BaseObject *opClone = (BaseObject* )op->GetClone(0,trans);
            #else
                BaseObject *opClone = (BaseObject* )op->GetClone(COPYFLAGS_0,trans);
            #endif
              
                Bool autoKeyOn = IsCommandChecked(IDM_AUTOKEYS);
                if(!autoKeyOn) CallCommand(IDM_AUTOKEYS);
              
                Bool plaKeyOn = IsCommandChecked(IDM_A_PLA);
                if(!plaKeyOn) CallCommand(IDM_A_PLA);
              
                CalculatePoints(op);
                op->Message(MSG_UPDATE);
              
                doc->SetTime(time);
                doc->AutoKey(opClone,op,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE);
              
                if(!autoKeyOn) CallCommand(IDM_AUTOKEYS);
                if(!plaKeyOn) CallCommand(IDM_A_PLA);
              
                BaseObject::Free(opClone);
            

            It's probably not the most efficient way to do it, but it does work. 😂

            Adios,
            Cactus Dan

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