PLA tracks?

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://plugincafe.maxon.net/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

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.

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;  
}  

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