Skip to main content
Kobek
Participant
January 18, 2016
Answered

Linking multiple layers to one main layer

  • January 18, 2016
  • 3 replies
  • 686 views

Hey there.

I have a script, in which I have a for loop to duplicate a layer a certain amount of times.
I was wondering how can I then link the effect properties of all the newly duplicated layers to the original one.

I was thinking of acessing the PropertyGroup of my effect on every laye and then, for every property, to set an expression, linking to the original layer.
Unfortunately I couldn't find anything in the scripting references witch could allow me to loop through all the properties of an effect.


If my description wasn't clear...here' what I want (more or less) the script to do:
Say you have 1 layer with a "fill" effect apllied on it.
I want my script to duplicate that layer a certain amount of times, and then link the fill color of all the new layers to the fill color of the original one.
Note this is not my actual script, just a simplified example of what I need to achieve.

I would be very grateful if someone can give me a rough idea of how I might accomplish this, or reference me to where in the scripting guide I can find more info about the matter.

Thank you in advance

This topic has been closed for replies.
Correct answer UQg

The scripting guide doesnt say anything about it.

You need to use the duplicate() methods of the layer and of the effect, then set a correct expression that will link the duplicates to the original.

To set an expression, just do myProperty.expression = myExpression; (string)

You need to make sure that the initial layer and effect both have a unique name.

Sample code (will work for most effects, except Paint, and few others, which has a more complexe property tree):

var numDuplicates = 15;

var comp = app.project.item(1);

var mainLayer = comp.layer(1);

var index = mainLayer.index;

var mainEffect = mainLayer.effect("ADBE Fill");

var effectPath = "thisComp.layer(\""+mainLayer.name+"\").effect(\""+mainEffect.name+"\")";

// create a 1st duplicate, and link the effects properties:

var dup = mainLayer.duplicate();

var effect = dup.effect(mainEffect.propertyIndex);

var n, N=effect.numProperties;

for (n=1; n<=N; n++){

    if (effect.property(n).canSetExpression){

        effect.property(n).expression = effectPath+"("+n+");";

        };

    };

dup.moveAfter(comp.layer(++index));

// duplicate more times (numDuplicates-1 times)

for (n=1; n<numDuplicates; n++){

    dup.duplicate().moveAfter(comp.layer(++index));

    };

Xavier

3 replies

Kobek
KobekAuthor
Participant
January 19, 2016

Hey, thanks for the quick and useful replies. I managed to get what I needed and also learned some cool stuff from the examples you guys posted.
Thanks a lot

January 19, 2016

loop through all the properties of an effect is the basic of many charming scripts.

function recursiveScanLayerForExpr(ref) {

    if (ref != null) {

      var prop;

      for (var i = 1; i <= ref.numProperties; i++) {

        prop = ref.property(i);

          if ((prop.propertyType == PropertyType.PROPERTY) && (prop.expression != "") && prop.canSetExpression) {

            /**********set your expression here**********/

          } else if ((prop.propertyType == PropertyType.INDEXED_GROUP) || (prop.propertyType == PropertyType.NAMED_GROUP)) {

            if ((prop.matchName=="ADBE Layer Styles"&&prop.canSetEnabled==false)||(prop.matchName=="ADBE Material Options Group"&&prop.propertyGroup(prop.propertyDepth).threeDLayer==false)||(prop.matchName=="ADBE Audio Group"&&prop.propertyGroup(prop.propertyDepth).hasAudio==false)||(prop.matchName=="ADBE Extrsn Options Group")||(prop.matchName=="ADBE Plane Options Group")||(prop.matchName=="ADBE Vector Materials Group")){

           

            }else{

                recursiveScanLayerForExpr(prop);

                }

          }

    }   

}

stib
Inspiring
January 19, 2016

Nice.

Here's how I do it. The function getPropertiesFromLayer(layer) takes a layer object and returns all properties of that layer.

function getPropertiesFromLayer(theLayer){
    var props = [];
    for(var p=1; p<= theLayer.numProperties; p++){
        if (theLayer.property(p)){
            propertyGroup = theLayer.property(p);
            var newProps = traversePropertyGroups(propertyGroup);
            if (newProps.length){
                for (var i = 0; i < newProps.length; i++) {
                    props.push(newProps);
                }
            }
        }
    }
    return props;
}

function traversePropertyGroups(pGroup){
    if (pGroup){
        var props = [];
        //alert(pGroup.numProperties);
        if (typeof pGroup.numProperties !== 'undefined'){

            for(var pp=1; pp<= pGroup.numProperties; pp++){
                var newProps = traversePropertyGroups(pGroup.property(pp));
                if (newProps.length){
                    for (var i = 0; i < newProps.length; i++) {
                        props.push(newProps);
                    }
                }
            }
        } else {
            props.push(pGroup);
        }
        return props;
    }
}

to save rewriting it each time I put this function in its own script file (called getPropsFromLayer.jsx), and then use

#include getPropsFromLayer.jsx

in any scripts that need it.

UQg
UQgCorrect answer
Legend
January 18, 2016

The scripting guide doesnt say anything about it.

You need to use the duplicate() methods of the layer and of the effect, then set a correct expression that will link the duplicates to the original.

To set an expression, just do myProperty.expression = myExpression; (string)

You need to make sure that the initial layer and effect both have a unique name.

Sample code (will work for most effects, except Paint, and few others, which has a more complexe property tree):

var numDuplicates = 15;

var comp = app.project.item(1);

var mainLayer = comp.layer(1);

var index = mainLayer.index;

var mainEffect = mainLayer.effect("ADBE Fill");

var effectPath = "thisComp.layer(\""+mainLayer.name+"\").effect(\""+mainEffect.name+"\")";

// create a 1st duplicate, and link the effects properties:

var dup = mainLayer.duplicate();

var effect = dup.effect(mainEffect.propertyIndex);

var n, N=effect.numProperties;

for (n=1; n<=N; n++){

    if (effect.property(n).canSetExpression){

        effect.property(n).expression = effectPath+"("+n+");";

        };

    };

dup.moveAfter(comp.layer(++index));

// duplicate more times (numDuplicates-1 times)

for (n=1; n<numDuplicates; n++){

    dup.duplicate().moveAfter(comp.layer(++index));

    };

Xavier