Effect's index
Copy link to clipboard
Copied
Hi!
I have a problem to get an Effect's index. I tried to solve my problem by getting the Effect's name, and it works fine, except if user gives that name twice, so I'm still stucked...
How can you return the Effect's index, usable by Script? For example, my effect is the second effect applied on my layer, how can I get this "2" index?
I figured out how to get layer's index, comp's unique_ID, but see no reference for effect's index into the SDK documentation...
I also tried to iterate with AEGP_GetLayerNumEffects and compare effect_refH, but it doesn't work...
Does anyone know a way?
Thanx,
François
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
I found a work around, by changing the name of my effect, calling it by script with the new name, then re-give the old name, but there must be something more simple...
Any idea?
Thanx
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Hi Shachar!
Thanx for the reply...
Well, it seems I did "not so bad", as i don't have to loop through the whole project, but it's still a bit surprising not to be able to access the index.
So, for those who need it, here's the process:
AEGP_RegisterWithAEGP -> get the plugin's ID
AEGP_GetNewEffectStreamByIndex -> get the stream of 1 parameter (no matter which one)
AEGP_GetNewParentStreamRef -> get the Effect's stream
AEGP_GetStreamName -> get the name (not the matchName)
AEGP_LockMemHandle -> store the OldName somewhere
AEGP_SetStreamName -> give a new Name
Then, you can access your effect by its name with Scripts... And your script can re-send you the Index if you need.
Rename your effect with the OldName, and dispose the streams.
By the way, I have a few more questions:
I've been testing some actions (changing a MaskShape) with Scripting, and directly from AEGP, and it seems scripting is faster. Do Script's engine and Effect's engine run at the same time?
And it leads to my 2nd question: is it possible to call ActionScript from an AEGP? Cos' it would be great to have 3 engines running at the same time to get a fast result...
And is it possible to call GPU calculations without switching to openGL?
That's a lot of questions, but you seem to have a lot of answers! 🙂
Thanx!
François
Copy link to clipboard
Copied
that whole changing-the-effect's-name-and-back thing seems a bit shady to me, as it creates a change in the project for the sole purpose of finding the index...
you could check some piece of sequence_data to tell if your check has hit the right instance, or better yet, a PUI_ONLY hidden param, who's changes don't falg the project as "dirty".
but as long as you're happy with your solution, i'm happy. 🙂
as for sciprts running while a plug-in is executing,
as far as i know, only one API is active at a time.
you can call a script from within a plug-in, but that plug-in will hold until the script returns.
same goes for actions script. i guess you can call it from within your plug-in and even from a javascript ran from within a plug-in, but as far as i know, their operations will queue, and not parallel.
about scripts changing masks faster than the API,
the script engine is a plug-in, much like any other AEGP. as far as i know, to maniuplate the project, the script plug-in translates the java commands to the C++ api commands that we all use.
so pehaps the extra speed is because the JS loop uses the C API more efficiently than the C++ loop you created.
if you're keyframing the mask shape, then perhaps it's a matter of using StartAddKeyframes(). it's supposed to make a big difference in performance hen adding a mass amount of keys.
GPU-wise,
i'm not too experienced with it. there are some other guys in the forum whore are far more familiar with openGL than me.
what i can tell you is that like any other facility the computer has, you can access the GPU using AE's API, or you can access it yourself directly.
so a plug-in doesn't have to be all around GPU based, to use the GPU.
even if you do use AE's access of the GPU, you still can do as much CPU calculations as you'd like. you don't HAVE to be polite and use up your declared intention of using the GPU.
not all your questions were fully answered,
but i hope some of that helps you make some sense of whole thing.
Copy link to clipboard
Copied
Hi Shachar!
It's a lot of answers, and it'll take months for me to truly understand them all !
About the extra speed, I don't keyFrame my MaskShape, just SetValue()
What I saw is C++ is faster to get Mask Vertices infos, and JS faster to set them (I used the same loops to read / write, so difference must be somewhere else, deeeeeep inside AE)
I could'nt tell you why, but it's still good to know, right? 🙂
And something totally different: how do you make a Scale parameter? with a link between x_scale and y_scale, just like Geometry one? I guess I have to make an Arbitrary parameter, but I couldn't find any example...
Thanx again!
François
Copy link to clipboard
Copied
i think the cs6 SDK offers a 3D param type.
i don't know if you can lock the dimensions together or not...
to create that link icon you'll need to create a custom UI.
i have to warn you that this is a pain to pull off.
should you decide to do so, start from the CorlorGrid sample.
it shows an ECW interface that responds to clicking.
i can think of another solution for you...
create 2 separate sliders for "x" and "y", and a checkbox for "link".
make the 2 sliders supervised, so when the user drags one, you get a USER_CHANGED_PARAM call, and you can update the value of the other.
(given the link checkbox is on)
that would be by far the simplest way to pull it off.
Copy link to clipboard
Copied
I made it with 2 sliders already, but I'll have a look at the ColorGrid, see if it can look better !
Thanx again for your help!
François
Copy link to clipboard
Copied
keep in mind that if you creat an arb param with a custom UI for both the x and y values together, the user won't be able to edit the value and speed graphs separately, as he can in the case of the scale or position params.
Copy link to clipboard
Copied
You're right, I'll try to do the most handy...
Thanx again!
François
Copy link to clipboard
Copied
Hi Shachar!
I have another question for you :
I have a plugin that performs maskshape transformation.
The transformations are called when the layer is rendered.
But I would need to transform my maskshape even if the layer is not rendered.
For example, if opacity on my layer is set to 0, or if a bigger layer is above that layer and fully hides it...
Is there a way to call my function when my original maskshape is modified (even if it doesn't affect the output of the layer)?
If you have a solution, or even the beginning of a clue, it will be a great help!
Thanx,
François
Copy link to clipboard
Copied
why yes.
create an invisible slider in your effect, and put an expression on it,
linking it to the mask shape.
so now whenever the user changes the mask shape it will change the slider
on you effect and trigger a re-render.
it's sort of a hack, but it saved my #ss a couple times before.
Copy link to clipboard
Copied
Smart!!!!
Thanx a lot!
François
Aaaaargh !!
It was too beautifull... I don't see any expression that would depend on the maskShape.
There is no expression that can access maskShape, except if it's applied on a... maskShape!
I tried with maskShape.propertyIndex, or this kind of stuff, but this is fix value, so it doesn't update the render...
Any idea?
Copy link to clipboard
Copied
hhmmm... in earlier versions of AE,
mask("Mask 1").maskPath.value.toSource();
would give you some number, that doens't imply the shpae, but would change when the shape changed...
it now seems to be gone. 😞
no dispair!
it can get a bit messier, but still solvable!
add a mask to your own layer, connect it to that other mask you want to track,
and add a hidden mask param to your effect reading your own local mask.
when the user changes your target mask, it changes your local mask, and the mask param triggers a re-render.
perhaps there's also a way to make that local mask invisible by making it's stream hidden...
Copy link to clipboard
Copied
Thanx again!
This is great help!
Cheers,
François
Copy link to clipboard
Copied
Hey Shachar!
I couldn't fix my problem yet, but for the mask expression, I found a way to get that changing number :
instead of "mask("Mask 1").maskPath.value.toSource();" it now works with "mask("Mask 1").maskPath[0];"
Do you know where this number comes from?
Some path encoding?
In which language?
Weird... but still there! 🙂
Cheers,
François
Copy link to clipboard
Copied
nice!!!
i didn't remember how i did it back then! i don't even know if that was the
way...
well, since all non-primitive data in JS is actually a pointer, the i guess
that the number is just the random result of the casting of first 4 bytes
of the pointed-to chuck to a float. so i can't tell what that park of the
chunk is...
so now that the number changes when the mask changes, does it not trigger a
re-render?
Copy link to clipboard
Copied
Well, no...
But I think there's another issue in my effect... time for code cleaning!
I'll let you know when... I understand my own plugin
Thanx,
François
Copy link to clipboard
Copied
Hi Shachar!
I've finished cleaning my code. Can I go out and play ? 🙂
More seriously, I still can't force render. But I don't think the problem comes from the slider.
I've tried changing the value of other parameters, by code and by hand, but it seems After Effects is smart enough not to process anything if opacity is set to 0.
But thanx for the help!
Cheers,
François
Copy link to clipboard
Copied
you may not go out and play without adult supervision. (well, actually that depends on the quality of your neighborhood...)
you're correct in your assesment that AE won't call a layer (and there fore it's applied plug-ins) if the opacity of the layer is 0, or if the layers above are fully opaque, so the said layer is not seen.
i can think of a couple of hacks, but they're not going to be easy (or fun)...
1. create an AEGP that will monitor changes in the "masks of interes" at idle time.
2. tell AE your plug-ni generates audio (i don't remember the falg's name). AE will give you a render_audio call even if the layer opcity is 0, and even if it's disabled. 🙂
(there are some condition, problems and caveats, but hey, we're trying to go against AE's rendering logic...)
Copy link to clipboard
Copied
Hi Shachar!
Using the Audio to call Video render... you must have a really twisted mind! 😉
It's a really smart hack, it opens a world of new possibilities...
Thanx a lot!
Cheers,
François
Copy link to clipboard
Copied
"i'm not crazy! my mother had me tested!" (s. cooper)
let's not crack open the champagne just yet...
we need to see if there aren't any hidden problems first.
Copy link to clipboard
Copied
Hi Shachar!
It seems champagne will stay on its shelf for a while...
I was tesing my plugin, trying to force re-render, and I did something I didn't try yet : simply render my composition.
And here is the big surprise: my plugin doesn't do anything when AE is actually rendering!!!
Here is how my plugin works:
It's an effect, applied on a layer with 2 masks.
First mask is the Master, 2nd mask is the Slave.
The plugin takes the Path value of the Master (vertices, tangents), performs transformation on these values, and applies them to the Slave.
There is a render call, only using "PF_COPY", so the maskShape transformation is called for every frame. Transformation is processed by scripting.
When I change any of those values (maskShape, transformation), the second Mask is transformed just fine.
When I launch a RAM preview, or a spaceBar preview, it also works fine...
But nothing happens when rendering (I mean through the render queue).
So, even if it's a really good way to make a trial mode on an effect, it's a bit anoying!
Could it be because maskShape transformation is performed by scripting?
So, it would mean no scripting can be called for actual render...
Cheers,
François
Copy link to clipboard
Copied
oh man...
listen.
what's happening is this:
during previews (not during "real" rendering), AE calls for your plug-in to
render. your plug-in in turn, changes the mask on it's own layer, therefore
invalidating the render (since the layer has changed), thus launching an
immediate re-render of the same frame. the new render doesn't cause a
change (because the salve mask stays as it was), and the loop breaks.
during a "real" render, AE calls for the render of a frame, and moves on to
the next, even if the current frame should be invalidated by the change.
since your plug-in's manipulation takes effect only at the second
iteration, you never see the result.
so...
what is it that you do with the slave mask?
if i knew a bit more perhaps i could find a solution.
Copy link to clipboard
Copied
Well, I have anchorPoint, Position, Scale and Rotation parameters, and I use these parameters to simply apply transformations to maskShape.
All the Geometry you can apply to a layer, you can apply to a mask with this effect.
I also have another version, with per-vertex transformations.
So, the Slave is just the result of the transformed Master.
This is really handy, at least if you can render...
Cheers,
François
Copy link to clipboard
Copied
ok... this is not a full solution, because it makes the plug-in work in a
different way, but here goes:
1. read the original image using PARAM_CHECKOUT, which brings you your
source without masks or effects.
2. render the mask separately using the suite who's name i don't remember.
(i think it's in the "pathmaster" example)
3. transform the rendered mask buffer using transform_world()
4. combine the original image with the transformed mask.
i know, it's a completely different process than what you did, but it will
give a similar result without the rendering loop mess.


-
- 1
- 2