PLA animation in C++?

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 04/01/2005 at 20:41, xxxxxxxx wrote:

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

---------
Okay, I've checked out every topic on this board. The few which deal with PLA keys and such are strictly COFFEE. C++ does not have a PLATrack and there is not a single example or clue on how to go about creating track, sequence, keys (at the last has a PLAKey) for PLA in C++.

Just ONE example would be nice. Maybe I'm not getting it, but I don't even know whether to use AllocValueTrack(), AllocDataTrack() (my choice), or AllocTimeTrack().

Help and thanks,
Robert

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 05/01/2005 at 00:55, xxxxxxxx wrote:

I think that I have it figured out. Setting the VariableTag data size had me stuck until I realized VariableChanged was the only way to update the size.

Once and for all, the first topic with PLA keys in C++:

  
// Create PLA Key from specified source and destination BaseDocument doc, BaseObject obj, BaseTime time  
void AnimLoader::CreatePLAKey(PointObject *sobj, BaseDocument *ddoc, BaseObject *dobj, const BaseTime &time;)  
{  
     BaseTrack *track;  
     // Check for Spla track, create if none  
     if (!(track = dobj->GetTrack(Spla)))  
     {  
          if (!(track = BaseTrack::Alloc(Spla))) throw ErrorException(ERROR_MEMORY, "AnimLoader.CreateKeyFrame.track");  
          ddoc->AddUndo(UNDO_NEW, track);  
          dobj->InsertTrackLast(track);  
     }  
  
     // Check for Spla sequence, create if none  
     BaseSequence *seq = NULL;  
     for (seq = track->GetFirstSequence(); seq; seq = seq->GetNext())  
     {  
          if ((time >= seq->GetT1()) && (time <= seq->GetT2())) break;  
     }  
     if (!seq)  
     {  
          if (!(seq = track->AutoAddSequence(ddoc, time))) throw ErrorException(ERROR_MEMORY, "AnimLoader.CreateKeyFrame.seq");  
          ddoc->AddUndo(UNDO_NEW, seq);  
     }  
  
     // Add KeyFrame  
     PLAKey *key;  
     if (!(key = PLAKey::Alloc())) throw ErrorException(ERROR_MEMORY, "AnimLoader.CreateKeyFrame.key");  
     ddoc->AddUndo(UNDO_NEW, key);  
     key->SetTime(time);  
     seq->InsertKey(key);  
  
     // Add PLA data  
     LONG count = sobj->GetPointCount();  
     VariableTag *vtag;  
     if (!(vtag = key->GetPointTag())) throw ErrorException(ERROR_MEMORY, "AnimLoader.CreateKeyFrame.vtag");  
     // Update array size of vtag  
     VariableChanged vc;  
     vc.old_cnt = vtag->GetDataCount();  
     vc.new_cnt = count;  
     if (!vtag->Message(MSG_POINTS_CHANGED, &vc;)) throw ErrorException(ERROR_GENERAL, "AnimLoader.CreateKeyFrame","PLA data creation failed");  
     if (count != vtag->GetDataCount()) throw ErrorException(ERROR_GENERAL, "AnimLoader.CreateKeyFrame","Mismatched Point Count");  
     CopyMem(sobj->GetPoint(), vtag->GetDataAddress(), count*sizeof(Vector));  
     vtag->Message(MSG_UPDATE);  
}  

The source object "sobj" is used as the point source for the PLA VariableTag data. Destination BaseDocument "ddoc" contains the PointObject "dobj" that gets the track/sequence/key. Time is the frame at which to insert the key.

Robert

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/02/2007 at 08:11, xxxxxxxx wrote:

I there any way to create PLA like function above with C4D 10.0 SDK?

thanks,
Remo

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/02/2007 at 08:26, xxxxxxxx wrote:

It can be done, but there are currently limitations of how this can be done. For instance, the VariableTag is no longer available so one must use CTrack::FillKey() with the object containing the track having had its points 'changed' to get the PLA data stored.

This code is not identical to the previous code - in that it is used to convert an animated, rigged figure into an animated Polygon object using PLA. So you'll have to make the changes to reflect the inputs and results desired.

#ifdef     C4D_R10  
// Fix Animation onto Polygon object as PLA track  
//*---------------------------------------------------------------------------*  
Bool FixPolygonAnimation(BaseDocument* doc, PointObject* orig, PointObject* root, LONG fixAnimSample, Real fixAnimBias, BOOL fixAnimSmooth, 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,0);  
     CTrack*               track =          root->FindCTrack(descID);  
     if (!track)  
     {  
          track =          CTrack::Alloc(root, descID);  
          if (!track)     return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MEMORY_TEXT), "FixPolygonAnimation.track");  
          root->InsertTrackSorted(track);  
          doc->AddUndo(UNDO_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 fixAnimSample 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 =                    0;  
  
     BaseObject*          csto;  
     PointObject*     defd;  
     CKey*               key;  
     const Vector*     spoint;  
     Vector*               points;  
     Vector*               lpoints;  
     DescID               biasDID =          DescLevel(CK_PLA_BIAS, DTYPE_REAL,0);  
     DescID               cubicDID =          DescLevel(CK_PLA_CUBIC, DTYPE_BOOL,0);  
     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 += fixAnimSample)  
     {  
          stime =               BaseTime::BaseTime(startf, fps);  
          // - Animate Document to change the points of orig  
          doc->SetTime(stime);  
          doc->AnimateDocument(NULL, TRUE, TRUE);  
          //doc->AnimateObject(orig, stime, 0L);  
          EventAdd();  
          if (!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, mcd))     return ErrorException::Throw(EE_DIALOG, GeLoadString(IPPERR_MODELINGCOMMAND_TEXT), "FixPolygonAnimation");  
          csto =          static_cast<BaseObject*>(mcd.result->GetIndex(0));  
          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::Throw(EE_DIALOG, GeLoadString(IPPERR_MEMORY_TEXT), "FixPolygonAnimation.key");  
          }  
          doc->AddUndo(UNDO_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     WIN64  
          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(fixAnimBias), 0L);  
          key->SetParameter(cubicDID, GeData(fixAnimSmooth), 0L);  
  
          BaseObject::Free(csto);  
  
          // Update progress bar on each frame  
          StatusSetBar(((*partial)*100L)/elements);  
          (*partial)++;  
     }  
     // Clear global matrix  
     Matrix     unit;  
     root->SetMg(unit);  
     return TRUE;  
}  
#else // Pre-R10 PLA  
...

Take care,

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/02/2007 at 08:33, xxxxxxxx wrote:

Big thanks Robert, will try it.

I just need to save PhyTools simulation data from array into PLA.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/02/2007 at 09:23, xxxxxxxx wrote:

Not sure but what are
ID_ANIM_PLA, CK_PLA_BIAS, CK_PLA_CUBIC ?
Can not find them in SDK.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/02/2007 at 10:00, xxxxxxxx wrote:

OK sorry found them in "modules\newman\res" c4d_symbols.h and ckpla.h :)

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/02/2007 at 10:10, xxxxxxxx wrote:

Yes, in modules:newman:res.

Be careful with XCode - it cannot handle both your c4d_symbols.h and the one there (this is a known issue that will be fixed in the R10 update). I ended up doing something like this as a workaround until then:

#ifdef     C4D_R10 // my preprocessor  
     #ifdef     XCODE // my preprocessor  
          enum  
          {  
               ID_ANIM_PLA               =     100004812  
          };  
          #include "ckpla.h"  
     #else  
          #include "newman\res\c4d_symbols.h"  
          #include "newman\res\description\ckpla.h"  
     #endif  
#endif

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/02/2007 at 10:13, xxxxxxxx wrote:

Yes I know this problem, I have just have create my own enum for this.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/02/2007 at 02:24, xxxxxxxx wrote:

just one note, accessing PLA info through the SDK is not yet finalized. there will be probably some changes in SDK at a later point, with direct access to the PLA data. can't say when these changes will be made though.

cheers,
Matthias