• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

toComp method on Puppet Pin position property returns bogus values

New Here ,
Mar 14, 2014 Mar 14, 2014

Copy link to clipboard

Copied

In trying to rig this girl character I've had a strange behaviour come up. I could work around it easily enough but it's getting to me that there's something I'm not understanding. My level of experience with expressions is relatively low but I have some Javascript experience so the main principles are clear.

What's annoying me is that my procedure works fine in a simple scene created wholly in AE. However when I import a .psd file (using composition-retain layer sizes), the same approach becomes useless. I feel like I'm missing something about layer sizes in relation to comps or something, or come upon a bug.

Ok this is my first post and its a little involved. I've always been able to find answers by searching online or in documentation. Here goes.

I'm trying to set up a character using Puppet Pins, which I will link to nulls as part of a more complicated setup down the road. My general approach is to set up the pins first and see how it all moves manually before creating nulls and linking the pins to the positions of the nulls. So far so simple. To get my nulls to the exact position of my pins, i pickwhip the null position to the pin position, see what the coords are, then remove the expression and put in the coords manually on the null. Once the nulls and pins are lined up, I just link the pins to the nulls with an expression in the pins "position" property.

This all works fine in my simple scene consisting of a solid layer with puppet pins applied, and some nulls. The nulls snap to the pins perfectly, and I don't have to convert the pin coordinates to comp space or anything. The pins coords seem to be in comp space already. Then I can link the pins to my nulls and all is fine.

However, in my complex scene which is generated from an imported .psd, the pin coords do not correspond to comp space. They're very low and seem to match up to the layer the puppet effect was applied to. So the null ends up way off near the top left of the comp.

No problem. We just run toComp on the position of the pin and we should get the comp space coords of the pin. But I don't. I get something way off.

Why do the pin positions not map to comp space automatically in my psd-based comp, as they did with the simple comp?

Is it even possible to run toComp successfully in the following way

toComp(thisComp.layer("R_Arm").effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position);

or is the return of

thisComp.layer("R_Arm").effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position;

not of the right data type to be an argument of toComp?

Are pin coordinates just layer based coordinates like any other or are there other factors involved?

I'd like to be able to set up pins where I want them and link them to nulls with exactly matching coordinates so the artwork doesn't jump when I link them.

More generally, is there any attribute of a psd file that can affect the coordinate system of a comp generated on import. The file in question contained all regular layers, plus one group of 3 (which came in as a pre-comp the entire size of the main comp, as expected), no layer effects or anything else fishy.

Anyone more experienced with expressions and coordinate spaces in AE have any idea what I'm missing?

Macbook Pro Early 2011 15" i7 2.2Ghz

16gb RAM

AMD Radeon 6750 1GB

OSX 10.9.2

AE 12.2.1.5

TOPICS
Expressions

Views

2.8K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Mar 15, 2014 Mar 15, 2014

I think that would be something like this:

L = thisComp.layer("Blue Solid 1");

L.toComp(L.effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position)

Dan

Votes

Translate

Translate
LEGEND ,
Mar 15, 2014 Mar 15, 2014

Copy link to clipboard

Copied

Well, first off: Since you claim to have experience in JS, then why the heck don't you simplify your setup by declaring your own variables? This is a bloody eyesore and would be a complete nightmare to deal with when adding further code. That said, .toComp() is still a method, so you need to tell it on which data to operate:

myPin.toComp(myPin.position)

That's probably the point of failure in your setup. It only accidentally works in your otehr scenario since when the mesh fits within the comp bounds, the coordinates will always be identical to begin with (if you don't move the layer, that is).

Mylenium

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 15, 2014 Mar 15, 2014

Copy link to clipboard

Copied

Hi Mylenium,

Sorry for my lack of variables.

I tried it again with a variable for the pin (myPin1) and tried calling .toComp in the following manner:

myPin1 = thisComp.layer("R_Leg").effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1");

myPin1.toComp(myPin1.position);

This throws up an error, "function 'myPin1.toComp' is not defined", so I presume that the value that is returned to variable myPin1 doesn't have a method ".toComp".

If I remove the myPin and just pass the position property of myPin1 to toComp as a function,

myPin1 = thisComp.layer("R_Leg").effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1");

toComp(myPin1.position);

it doesn't error, it returns some coordinates, but not the right ones.

Just as a test, I made a second null layer and did this in its position expression:

myNull = thisComp.layer("Null 20");

myNullpos = myNull.toComp(myNull.anchorPoint);

The second null mapped perfectly to the first with identical coords.

Same result for this:

myNull = thisComp.layer("Null 20");

myNullpos = myNull.position;

Try:

    

myNull = thisComp.layer("Null 20");

myNullpos = myNull.anchorPoint;

And I get 0,0  , presumably because the anchorPoint coords are layer coords. The anchorpoint of a null is at 0,0 on the layer by default.

Now if I try one more permutation calling myNull.toComp on the myNull.position property (a composition space position coordinate):

myNull = thisComp.layer("Null 20");

myNullpos = myNull.toComp(myNull.position);

I get a position way off to the bottom right.

So what I take from all this is:

1- I can use .toComp with my null layer as myNull.toComp() but not with myPin1 as myPin1.toComp(). I presume whatever is returned by the pin query doesn't have a method .toComp, while the null layer returned to variable myNull, does. So maybe its not possible to get comp space coordinates of a pin using this approach. Like it only works for layers not sub-layer items like pins.

2- Using myNull.toComp(), I get the right result passing myNull.anchorPoint. I also get the right result if I dispense with .toComp and just use myNull.position, so presuably they're equal. Using just myNull.anchorPoint gives the position of the anchor within the layer (0,0 by default) and using myNull.toComp() and passing myNull.position gives a position to the far bottom right of the correct one (presumably because myNull.position is already a comp space coord, I don't know the internals of .toComp).

So my conclusion thus far is that the pin position coords, when passed to .toComp() dont work, so they must be in some way differently defined than the anchorpoint of a null, which does work. whatever is returned by the pin query has no .toComp method.

The method seems to need an anchorPoint to be passed, and a pin position doesn't seem to serve the same purpose.

So is there a different method to get the comp space coords of a PP or is there some property of a PP which can be passed to .toComp?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 15, 2014 Mar 15, 2014

Copy link to clipboard

Copied

Thinking about this another way.

What if I define the problem like this:

I've seen lots of expressions that allow you to link a puppet pin to a null so that the puppet pin is child and follows the null.

If I wanted to do the opposite, make a null ( or other item) follow an individual puppet pin, how would I go about it? Presumably by putting an expression in the position property of the null which evaluates to the position of the pin on screen. But I can't figure what that expression would be.

Suggestions?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 15, 2014 Mar 15, 2014

Copy link to clipboard

Copied

I think that would be something like this:

L = thisComp.layer("Blue Solid 1");

L.toComp(L.effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position)

Dan

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 16, 2014 Mar 16, 2014

Copy link to clipboard

Copied

Hi Dan,

Thanks for your input. Satisfyingly for me () I had already arrived at the solution through thinking about the conclusions I drew from my post 2 above. Mainly that toComp is a method that needs to be called on a layer. I meant to update this with the solution but I figured it out with seconds before a rugby match began on TV and I forgot about it then.

So your answer is correct and right (unsurprisingly, your reputation precedes you). Here's my version anyway for the record.

myPin1 = thisComp.layer("R_Leg").effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position;

legLayer = thisComp.layer("R_Leg");

legLayer.toComp(myPin1);

I just have the extra line at the top declaring a variable for the pin.

Thanks to you and Mylenium.

Mark

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 16, 2014 Mar 16, 2014

Copy link to clipboard

Copied

LATEST

UPDATE: SOLVED

So thanks to the prompt from Mylenium about toComp being a method and therefore needing to be called on some object, I did the few experiments in post 2. It turned out that toComp wasn't a method of puppet pins so Mylenium's suggestion wasn't quite right. It has to be called on a layer.

So the final answer for me was

myPin1 = thisComp.layer("R_Leg").effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position;

legLayer = thisComp.layer("R_Leg");

legLayer.toComp(myPin1);

Call the method on a layer and pass it the pin position as an argument.

Dan Ebberts supplied me with the same solution while I was away figuring it out for myself.

L = thisComp.layer("Blue Solid 1");

L.toComp(L.effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position)

Thanks to both for making me think in the right direction (Mylenium) and supplying confirmation (for my own mind) that my solution is a good one(Dan).

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines