Skip to main content
Participant
September 6, 2015
Answered

Setting a value kills a script

  • September 6, 2015
  • 1 reply
  • 1015 views

I'm working on my first script and I've hit a bit of a snag.

I have added a slider expression to a layer to which I later add an expression.  (That part is working)  The first two lines in the following code work as expected.  Line one creates the slider effect and line two changes the name of the effect to the layer name plus what it controls.

Line three was intended to set the value of the slider, but if that line is left in the script, the script simply stops at that point, breaking out of the for loop that the code is in.  As near as I can tell, I'm trying to set a value to a read only property, but I don't know what property I should be working with.  I assume featherCrtl.property(1) is the slider's value... Maybe it's not.  But I don't know what else would be the value.

Any help would be greatly appreciated.

Thanks,

Lars

var featherCrtl = selectedLayers.property("Effects").addProperty("ADBE Slider Control");

featherCrtl.name = selectedLayers.name + " Feather Control";

featherCrtl.property(1).setValue(myFeather);

This topic has been closed for replies.
Correct answer UQg

Ok, it looks like I might have figured it out....

I stopped trying to change the property value using featherCrtl and instead used the code before assigning featherCrtl.  Adding line three below (what would be line 154 in the full code in my previous post) and referencing the name of the slider in that line, I am able to set the value as needed.  I also added the proper variation on this line to the opacityCrtl and expansionCrtl sliders.  Now the code seems to run without dropping out of the loop.

Assuming I don't manage to mess things up again, this might actually be a working script.

Lars

var featherCrtl = selectedLayers.property("Effects").addProperty("ADBE Slider Control");

featherCrtl.name = selectedLayers.name + " Feather Control";

selectedLayers.property("Effects").property(featherCrtl.name).property("slider").setValue(myFeather);


Yes, this is because when you add an effect to a layer, any reference to existing effects gets invalidated (some for maks, etc, ie anything that can be added).

So when you add the ' opacityCrtl', the previously defined variable 'featherCrtl' is no longer valid. You have to redefine it, or do as you just did, refer to the effect by its name.

Xavier.

1 reply

UQg
Legend
September 6, 2015

There doesnt seem to be anything wrong in these 3 lines.

What error message do you get ?

jagataiAuthor
Participant
September 7, 2015

Hi UQg,

Thank you for your response.

There is no error message that I can see.  The way I determined that there was a problem was by adding alerts to find out when the script fails.  While I am able to change the name property of the featherCrtl object, any attempt to view or modify the object afterward results in the script dropping out of the loop and failing to finish what it was doing.

I'm attaching the entire script as it is right now if anyone cares to look at it further.

featherCrtl is initialized on line 152.  Everything seems to run fine until it hits line 181 where the script attempts to set the value of featherCrtl.property(1)

(The same thing happens with the similar opacityCrtl and expansionCrtl objects.)

If I comment out lines 181, 183, 184, the loop finishes properly, but I can't set the values that I need.

Frankly, I'm stumped.  I suspect it's some bone-headed mistake that I've made, but I don't have the experience to track it down.

This is being run on a Mac running OS-X 10.10.3 in Adobe AE 2015.0.1 release  Version 13.5.1.48 (This behavior also occurs on the 2014 release.)

I appreciate any help you can give.

Thanks,

Lars

{

   

   

function myScript(thisObj) {

        function myScript_buildUI(thisObj) {

            var myPanel = (thisObj instanceof Panel) ? thisObj : new Window("palette", "Mask Feather", undefined, {resizeable:true});

            res = "group{orientation: 'row', alignment:['fill','top'], alignChildren: ['fill','top'] ,\

              groupOne: Group{orientation: 'column', alignment:['fill','fill'], alignChildren: ['fill','fill'] ,\

              myHelp: Button{text: 'Help', alignment:['left','top'], preferredSize:[-1,20]},\

              myStaticText4: StaticText{text: 'Fill In Values dont work yet.  Deal with It.'},\

              myStaticText5: StaticText{text: 'Version: 0.13'},\

              myRenameLayers: Checkbox{text: 'Rename Layers Based on First Mask Name'},\

              myLockMasks: Checkbox{text: 'Lock Masks after Modifying'},\

              myLockMasks: Button{text: 'Lock Masks', alignment:['left','top'], preferredSize:[-1,20]},\

              myUnlockMasks: Button{text: 'Un-Lock Masks', alignment:['left','top'], preferredSize:[-1,20]},\

              myStaticText1: StaticText{text: 'Set Mask Feather'},\

              myFeatherSet: EditText{value: 10, text: 'Enter Feather Value Here'},\

              myStaticText2: StaticText{text: 'Set Mask Expansion'},\

              myExpansionSet: EditText{value: -3, text: 'Enter Expansion Value Here'},\

              myExecuteFilledInValues: Button{text: 'Execute Filled In Values', alignment:['left','top'], preferredSize:[-1,20]},\

              myStaticText3: StaticText{text: 'Presets For Overlay Feather and Expansion'},\

              myExecutePreset1: Button{text: 'Feather: 10, Expansion -5', alignment:['left','top'], preferredSize:[-1,20]},\

              myExecutePreset2: Button{text: 'Feather: 20, Expansion -10', alignment:['left','top'], preferredSize:[-1,20]},\

              myExecutePreset3: Button{text: 'Feather: 40, Expansion -20', alignment:['left','top'], preferredSize:[-1,20]},\

              myExecutePreset4: Button{text: 'Feather: 4, Expansion -2', alignment:['left','top'], preferredSize:[-1,20]},\

              myExecutePreset5: Button{text: 'Feather: 6, Expansion -3', alignment:['left','top'], preferredSize:[-1,20]},\

              myStaticText7: StaticText{text: 'Presets for Blur Feather.'},\

              myExecuteBlurPreset1: Button{text: 'Feather: 30, Expansion 0', alignment:['left','top'], preferredSize:[-1,20]},\

              myExecuteBlurPreset2: Button{text: 'Feather: 60, Expansion 0', alignment:['left','top'], preferredSize:[-1,20]},\

              myExecuteBlurPreset3: Button{text: 'Feather: 30, Expansion 5', alignment:['left','top'], preferredSize:[-1,20]},\

              myExecuteBlurPreset4: Button{text: 'Feather: 60, Expansion 5', alignment:['left','top'], preferredSize:[-1,20]},\

              },\

}";

            myPanel.grp = myPanel.add(res);

           

// Presets

var renameLayers;

var lockMasks;

var executeHelpBTN = myPanel.grp.groupOne.myHelp;

var executeFilledInBTN = myPanel.grp.groupOne.myExecuteFilledInValues;

// Lock or unlock masks - assorted housekeeping functions.

var executeLockMasks = myPanel.grp.groupOne.myLockMasks;

var executeUnlockMasks = myPanel.grp.groupOne.myUnlockMasks;

// Overlay presets (for use without blur effect)

var executePreset1 = myPanel.grp.groupOne.myExecutePreset1;

var executePreset2 = myPanel.grp.groupOne.myExecutePreset2;

var executePreset3 = myPanel.grp.groupOne.myExecutePreset3;

var executePreset4 = myPanel.grp.groupOne.myExecutePreset4;

var executePreset5 = myPanel.grp.groupOne.myExecutePreset5;

// Blur layer presets

var executeBlurPreset1 = myPanel.grp.groupOne.myExecuteBlurPreset1;

var executeBlurPreset2 = myPanel.grp.groupOne.myExecuteBlurPreset2;

var executeBlurPreset3 = myPanel.grp.groupOne.myExecuteBlurPreset3;

var executeBlurPreset4 = myPanel.grp.groupOne.myExecuteBlurPreset4;

// Individually locks each mask on the selected layer

executeLockMasks.onClick = function lockMasks() {

    var activeItem = app.project.activeItem;

    var activeComp = activeItem;

    var selectedLayers = activeComp.selectedLayers;  // selectedLayers is a 0 based array.  while other things are indexed.

        for (var i = 0; i < selectedLayers.length; i++) {

            for( var count = 1; count <= selectedLayers.mask.numProperties; count++ ) {

            selectedLayers.mask(count).locked = 1;

            }

        }

    }

// Individually un-Locks each mask on the selected layer

executeUnlockMasks.onClick =function unlockMasks() {

    var activeItem = app.project.activeItem;

    var activeComp = activeItem;

    var selectedLayers = activeComp.selectedLayers;  // selectedLayers is a 0 based array.  while other things are indexed.

        for (var i = 0; i < selectedLayers.length; i++) {

            for( var count = 1; count <= selectedLayers.mask.numProperties; count++ ) {

            selectedLayers.mask(count).locked = 0;

            }

        }

    }

// Event watchers for buttons in the UI

// I guess this is one way to handle executing the presets, but I think it would be better if I had an array that contained the values (which could be loaded from a preference file)  and

// a way of loading those presets based on which button was pushed.  (Of course I'd have to be able to change the button text based on the data in the preference file)

// Whatever... that's a problem for another day.

// Applies filled in feather and expansion values

executeFilledInBTN.onClick = function setFilledIn() {

    // Holy Cow.  This actually works.

    myFeather = Number(myPanel.grp.groupOne.myFeatherSet.text);

    myExpansion = Number(myPanel.grp.groupOne.myExpansionSet.text); 

    setFeather(myFeather, myExpansion );

        }

   

// This kind of brute force method of executing the presets can still work with a dynamic set of preferences if I change the assignments to point to elements in an array.

// But I'll deal with that later.

executePreset1.onClick = function setPreset1() {var myFeather = 10; var myExpansion = -5; setFeather(myFeather, myExpansion );}

executePreset2.onClick = function setPreset2() {var myFeather = 20; var myExpansion = -10; setFeather(myFeather, myExpansion );}

executePreset3.onClick = function setPreset3() { var myFeather = 40; var myExpansion = -20; setFeather(myFeather, myExpansion, ); }

executePreset4.onClick = function setPreset4() { var myFeather = 4; var myExpansion = -2; setFeather(myFeather, myExpansion ); }

executePreset5.onClick = function setPreset5() { var myFeather = 6; var myExpansion = -3; setFeather(myFeather, myExpansion ); }

executeBlurPreset1.onClick = function setBlurPreset1() { var myFeather = 30; var myExpansion = 0; setFeather(myFeather, myExpansion); }

executeBlurPreset2.onClick = function setBlurPreset2() { var myFeather = 60; var myExpansion = 0; setFeather(myFeather, myExpansion ); }

executeBlurPreset3.onClick = function setBlurPreset3() { var myFeather = 30; var myExpansion = 5; setFeather(myFeather, myExpansion); }

executeBlurPreset4.onClick = function setBlurPreset4() { var myFeather = 60; var myExpansion = 5; setFeather(myFeather, myExpansion ); }

executeHelpBTN.onClick = function help_me_help_me() { alert("HELP!\rOkay.  Stop laughing.  This script is supposed to work better than this.\r\rAnyway, I've manged to break the presets so all they do is set up sliders and expressions,\rbut they don't actually set the values properly.\r\rI'm sorry.  I know I failed you.  Please stop hitting me."); }

//

//

// ---------- > Here's the main meat of the script. < ----------

//

//

function setFeather(myFeather, myExpansion) {

var activeItem = app.project.activeItem;

var activeComp = activeItem;

var selectedLayers = activeComp.selectedLayers;  // selectedLayers is a 0 based array.  while other things are indexed.

app.beginUndoGroup("Set Mask Feather and Expansion");

// This loop runs through all the selected layers.  The loop that runs through the masks is cantained within.

for (var i = 0; i < selectedLayers.length; i++) {

    var layerMin = 100000000;  // Set the value good and high so it is unlikely we'd ever have a situation where a layer in point was above this.

    var layerMax = 0;

    var frameLength = activeComp.frameDuration;

   

    // feed back as to what the script intended to set the feather and expansion settings to

    writeLn( " -- Feather = " + myFeather  + " Expand = " + myExpansion);

// ---> Some of the following code seems a bit redundant....

    //Sets Layer name to match the name of the first mask in that layer.

    if (myPanel.grp.groupOne.myRenameLayers.value == true ) {  renameLayers = 1; write("Renaming Layer. "); } else { renameLayers = 0; write("Not Renaming Layer. "); }

    // If the rename Layers setting was set, we will rename the layer using the name of the first mask in the layer.

    if (renameLayers == 1) {

        selectedLayers.name = selectedLayers.mask(1).name;

    }

    // Locks the masks if that setting has been set.

    if (myPanel.grp.groupOne.myLockMasks.value == true ) { lockMasks = 1; write("Locking Masks" );  } else { lockMasks = 0; write("Not Locking Masks"); }

// Since we don't plan to have a separate slider for every damn mask in a layer, it would be best to put the code to create the control sliders here before we start looping through masks.

// First we'll set up a few variables that contain the template text for the expressions.  If deemed suitable, we will add wimsical comments within the expression just to annoy the user.

var featherExpressionContents = "temp = effect(\"" + selectedLayers.name + " Feather Control\")(\"Slider\");\r[temp, temp]\r\/\/Gee, I\'d sure like a bite of your sandwich.";

var opacityExpressionContents = "effect(\"" + selectedLayers.name + " Opacity Control\")(\"Slider\");\r\/\/The cows fly swiftly over Brazil.";

var expansionExpressionContents = "effect(\"" + selectedLayers.name + " Expansion Control\")(\"Slider\");\r\/\/To lose one parent is tragic.  To lose both looks like carelessness.";

// Here we add the slider effects to the layer.  Note becase this is done outside the mask loop, we will only create these three sliders for the selected layers.  If we want to create sliders for each mask, we will have to do this work within the mask loop.

var featherCrtl = selectedLayers.property("Effects").addProperty("ADBE Slider Control");

featherCrtl.name = selectedLayers.name + " Feather Control";

// On the off chance that there was a problem with the name, I converted spaces into underscores.  Didn't work.

//~ var effectNameTemp = selectedLayers.name + " Feather Control";

//~ var effectNameNoSpace = effectNameTemp.replace(new RegExp(" ", "g") , "_");

//~ featherCrtl.name = effectNameNoSpace;

//~ alert( "Name: " + featherCrtl.name );

var opacityCrtl = selectedLayers.property("Effects").addProperty("ADBE Slider Control");

opacityCrtl.name = selectedLayers.name + " Opacity Control";

var expansionCrtl = selectedLayers.property("Effects").addProperty("ADBE Slider Control");

expansionCrtl.name = selectedLayers.name + " Expansion Control";

// The following line seems to break this code as well.  If I try to run this alert, I get dropped out of the script.

//~ alert("Slider Names:\r" + featherCrtl.name + "\r" + opacityCrtl.name + "\r" + expansionCrtl.name);

// The following code breaks the script.

// If the following lines are uncommented, we will not be able to get to the alert just after them.  While the UI is unaffected and I can continue to run the preset commands, I get kicked out

// of the code at this point.  As further verification, note that if the following code is uncommented, the script will not trim the layer to first and last keyframes.  If the code is disabled, then

// the loop completes properly and the layer is trimmed.

//

//Is it possible that there is some other bit of code that is createing a bad value that causes some error?  I am pretty bone-headed when it comes to this sort of thing and it almost goes without

// saying that there are probably some egregious beginnger miskates in this script.

//

// If the following worked, it would set the initial values on the sliders.  Alas it doesn't work and all i can do is weep into my beer.

// Any attempt to access any part of the following three variables causes the loop to terminate.  I can't figure out why.

featherCrtl.property(1).setValue(myFeather);

alert("Survived");

opacityCrtl.property(1).setValue(100);

expansionCrtl.property(1).setValue(myExpansion);

// alert( featherCrtl.property(1));

//~ alert(featherCrtl.property.slider.propertyValueType);

alert("Survived");

// Here is the loop that handles setting values on the individual masks.

    for( var count = 1; count <= selectedLayers.mask.numProperties; count++ ) {

//         Feed back on how many masks the script has found...

//       writeLn("There are " + selectedLayers.mask.numProperties + " to loop through.");

// Let's first make sure the mask we are working on is unlocked.  We'll lock it later if the setting is set.

         selectedLayers.mask(count).locked = 0;

               

// The next two lines are the original method of setting feather and expansion values.  This is to be superceeded by creating a slider and expression and linking them.

        //selectedLayers.mask(count).maskFeather.setValue([myFeather ,myFeather ]);   

         //selectedLayers.mask(count).maskExpansion.setValue(myExpansion);

        

// This code connects each mask property with its proper slider that was created just before going into the mask processing loop

        selectedLayers.mask(count).maskFeather.expression = featherExpressionContents;

        selectedLayers.mask(count).maskOpacity.expression = opacityExpressionContents;

        selectedLayers.mask(count).maskExpansion.expression = expansionExpressionContents;

// if we want, this is where we'll lock the mask after modifying

         if ( lockMasks == true ) { selectedLayers.mask(count).locked = 1 }

               

// The following code finds the first and last keyframes of all the mask paths in a layer.  If there are earlier or later keyframes in a property OTHER THAN mask path, this code will not find it.

// probably should re-write to look at other properties, although this should work for my work flow.

        if ( layerMin > selectedLayers.inPoint = selectedLayers.mask(count).maskPath.keyTime(1) ) {

            layerMin =  selectedLayers.inPoint = selectedLayers.mask(count).maskPath.keyTime(1);

            }

         if ( layerMax < selectedLayers.mask(count).maskPath.keyTime(selectedLayers.mask(count).maskPath.numKeys)) {

            layerMax =   selectedLayers.mask(count).maskPath.keyTime(selectedLayers.mask(count).maskPath.numKeys)+frameLength; // We add an extra frame otherwise the layer is trimmed one frame early.

            }

        } // End of mask processing loop

   

// Here's where we actually set the in and out trim positions of the layer based on earliest and latest keyframes in the mask path property of all masks in the layer.

// Perhaps it might be nice to have a checkbox to alllow the user to say whether they want the layer trimed.

        var trimLayers = 1;

        if ( trimLayers == 1 ) {

        selectedLayers.inPoint = layerMin;

        selectedLayers.outPoint = layerMax;

        }

    } // End of Layer processing loop

app.endUndoGroup();

  }; // End of setFeather Function

           

            // Setup Panel Sizing

           

            myPanel.layout.layout(true);

            myPanel.grp.minimumSize = myPanel.grp.size;

           

            // Make Panel Resizeable

           

            myPanel.layout.resize();

            myPanel.onResizing = myPanel.onResize = function() {this.layout.resize();};

           

            return myPanel;

            }

        var myScriptPal = myScript_buildUI(thisObj);

       

        if( (myScriptPal != null) && (myScriptPal instanceof Window)) {

            myScriptPal.center();

            myScriptPal.show();

            }

    }

 

    myScript(this);

    }

jagataiAuthor
Participant
September 7, 2015

Ok, it looks like I might have figured it out....

I stopped trying to change the property value using featherCrtl and instead used the code before assigning featherCrtl.  Adding line three below (what would be line 154 in the full code in my previous post) and referencing the name of the slider in that line, I am able to set the value as needed.  I also added the proper variation on this line to the opacityCrtl and expansionCrtl sliders.  Now the code seems to run without dropping out of the loop.

Assuming I don't manage to mess things up again, this might actually be a working script.

Lars

var featherCrtl = selectedLayers.property("Effects").addProperty("ADBE Slider Control");

featherCrtl.name = selectedLayers.name + " Feather Control";

selectedLayers.property("Effects").property(featherCrtl.name).property("slider").setValue(myFeather);