How to access PLA data
-
hey @ferdinand,
thanks for all the help. This code was very helpful, but I still get the same points, from different keys even if I create them with different times. Which makes me wonder if maybe I am creating them with the wrong parameters. I also tried using just one key and moving frame by frame, but still the points from the pointTag remained always the same.
Cheers, Facundo -
Hey @facumh,
As you can see in my screenshot, my code is reading the correct data for the two keys in the scene. Are you also creating the keys programmatically, or have the keys been created manually? Without your code, it will be hard for me to help you here.
Cheers,
Ferdinand -
Hey @ferdinand,
in my second comment you can see how I create the keys, programmaticallly. I know it's hard without the whole code, but so far this has being very educational for me as well, just wanted to thank you for that as well.
Cheers, Facundo -
Hey @facumh,
your code looks okay, at least when one wants to rely on
FillKey
(which we internally also do). The other route would be to do the inverse of what I showed in my code and manually write the arrays of the underlying PLAData.There are however two problems with your code, you use CTrack::FillKey which "Fills key with default values." But looking at our PLA baking code, this seems to respect the points and tangents of the passed
bl
, i.e., is smart enough to know what to do with the special track PLA.if ((flags & TL_FLAG_BAKE_PLA || flags & TL_FLAG_BAKE_ALL) && source->IsInstanceOf(Obase)) { desttrack = nullptr; if (bSearchTrack) desttrack = dest->FindCTrack(ConstDescID(DescLevel(CTpla, CTpla, 0))); if (!desttrack) { desttrack = CTrack::Alloc(dest, ConstDescID(DescLevel(CTpla, CTpla, 0))); GeListHead* head = dest->GetCTrackRoot(true); if (!head) return false; head->InsertLast(desttrack); } if (desttrack) { pKey = desttrack->GetCurve()->AddKey(time, &idx); if (pKey) { desttrack->FillKey(doc, source, pKey); if (flags & TL_FLAG_BAKE_CLEAN) CleanKeys(*desttrack, idx, *pKey, isLastFrame); } } }
There are however two other problems, first of all, you do not make sure to write to two unique time values, when
BaseDocument::GetTime()::Get() == 0.0
, then you will write to the same key. You also pass for both keysobj
as thebl
, creating the same default values for both keys.This is then likely the reason for you reading the same data on both keys.
Cheers,
Ferdinand -
hey @ferdinand ,
I did suspect usingobj
for both keys could be the issue, but then how would you suggest I extract the animated spline from the baseDoc ? -
Hey @facumh,
My point was that when you have an object
obj
whose points (and tangents) are in the stateX
and you use that object to fill the value(s) for a key, you will obviously end up with identical key values.So, you have to either manually write the key data, I already hinted at the fact that you could do that by doing the inverse of what I showed, to manually write the point and tangent data stored in a PLA key, or alternatively, you could change the state of
obj
, so that its points and tangents are not in the stateX
anymore. Otherwise, both keys will be filled with the stateX
.Cheers,
Ferdinand -
hey @ferdinand ,
sorry I should have explained a little more. So the first time this function is executed, there are no tracks, so I create the track and first key, based onObj
in state of time 0.0. On later executions, thedoc->getTime()
is no longer 0.0, and I thought this would mean that the baseObjectObj
would also have the point of the spline in this new time, and since now there is already a track, I create the new key usingObj
with the current time. This way and checking withkey = curve->FindKey(time)
and checking that it's not null, I make sure to not replicate keys with the same time hence (I thought), not two keys with the same state of `Obj.Thanks for your time and patience with all my doubts.
Cheers, FacundoEdit: sorry, not sure if it's clear, but what want is the position of the spline points in different moments of the animation and I thought with the pla tracks and keys this info could be retrieveed
-
Hey @facumh,
I understand what you want to do, you want to record a PLA key for the given object at the given document time. For which you could btw also just use the
CallCommand
for Record Active Objects:Just turn off position, rotation, scale, and parameter recording, and turn on PLA (just as shown in the screen above), then invoke "record active objects". Should be doable in less than 15 lines, including reverting to the previous animation recording state. You can use
CallCommand
to invoke all 6 buttons here. You can use IsCommandChecked to find out if a command is "blue" or not, so that you know when you must runCallCommand
to toggle the state and when not.Regarding your code, you showed us above that you write two keys:
auto const time = doc->GetTime(); const DescID plaID = DescLevel( CTpla, CTpla, 0 ); CTrack* plaTrack = obj->FindCTrack( plaID ); if( plaTrack == nullptr ) { plaTrack = CTrack::Alloc( obj, plaID ); if( plaTrack == nullptr ) throw maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION ); obj->InsertTrackSorted( plaTrack ); CCurve* curve1 = plaTrack->GetCurve(); if( curve1 == nullptr ) throw maxon::UnexpectedError( MAXON_SOURCE_LOCATION ); // set first key CKey* const key1 = curve1->AddKey( BaseTime( 0.0 ) ); if( key1 == nullptr ) throw maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION ); plaTrack->FillKey( doc, obj, key1 ); } // set second key CCurve* curve = plaTrack->GetCurve(); auto animatedParams = curve->GetInfo(); CKey* const key2 = curve->AddKey( time ); if( key2 == nullptr ) throw maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION ); plaTrack->FillKey( doc, obj, key2 ); GeData curveParams; auto foundParams = curve->GetParameter( plaID, curveParams, DESCFLAGS_GET::NONE ); auto geDataCurve = key2->GetGeData();
If you use other code, you should show us this, in fact you should always post executable code, as things otherwise tend to get convoluted
Cheers,
FerdinandPS: When I have time I will squeeze in a code example for recording the PLA state of the selected object at the current document time. But it might take me some time, I am a bit busy at the moment.
-
Hi @ferdinand ,
thanks for the tip of using Record Active Element.
On one hand I couldn't find the command id on the sdk website.
On the other hand, playing around with the RAE and the spline, I realized that whenever the active element is the spline and I press play, it doesn't move, but when it is not the active element, and I press play, then the animation moves. I'm using a rope expresion tag to animate it and rope belt tag to fixate one end of the spline.
This behaviour of the spline not moving when it's the active element would explain why I always get the same points on the different keys, even when the animation moves. But could you maybe explain this behaviour ?Cheers, Facundo
-
Hey @facumh,
Not all command IDs are exposed as symbols. The easiest way to find out their ID is the so-called Script Log. Simply invoke the actions you are interested in, and the look into the log. The Script Log is by default part of the Script layout.
Regarding your other question(s), these are unfortunately out of scope of support here, as they are end-user questions. I must ask you to direct them towards our end-user support via Support Portal: Support Request.
Thank you for your understanding,
Ferdinand -
Hi @ferdinand ,
Thanks very much for all of your time and tips!!
Facundo -