Copy link to clipboard
Copied
When working with smart objects and filters, Photoshop renders the layer data produced by the filter once and then uses the result for further processing. However, for some geometric filters (e.g. Polar Coordinates or Perspective Warp), the results of the filter pass would be different, given a different x/y displacement or canvas size. Sometimes results are not rendered at all outside the current canvas, so when moving the layer data, artefacts or empty areas might come into view.
Is there some prefered way (e.g. a shortcut or a script command) to force re-render of all or selected smart filters in a smart object layer to fill those areas with properly filtered data?
Copy link to clipboard
Copied
cmd-T, enter would seem like an option, doubleclicking any Smart Filter and hitting OK another.
Copy link to clipboard
Copied
Thank you for the answer. I should have been more clear. What you suggest, is exactly what I'm doing right now. However, I would like to to just re-render all (selected) layers without revisiting any input or preview windows.
Copy link to clipboard
Copied
Can you give a sequence of actions and a screenshot explaining your problem using the example of PolarCoordinates? I cannot reproduce the bug.
In order to recalculate the filter, it is enough to turn it off and on.
Code for one filter with index 1.
var d = new ActionDescriptor();
var r = new ActionReference();
r.putIndex(stringIDToTypeID("filterFX"), 1);
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("hide"), d, DialogModes.NO);
executeAction(stringIDToTypeID("show"), d, DialogModes.NO);
Copy link to clipboard
Copied
I did not want to imply, that there was a bug in PolarCoordinates, I think this is expected behavior. The source of the problem might have even been with the rendering of another geometric smart filter in the processing chain. I've attached a visualization of the problem with the Perspective Warp filter. It shows
1) The original application of the warp.
2) Changing the x/y translation and thereby moving the layer data towards the top left corner. Note the "empty", "unrendered" area on the bottom right.
3) Result after turing the filter off and on again. This solution seems to work for a single filter only. Turning the "Smart Filters" entry off and on again didn't have an effect.
I was hoping for some kind of built in "re-render" or "refresh" command, but solving it with a script using the "off/on" approach works as well.
Copy link to clipboard
Copied
There is such a bug / feature in Photoshop (I don’t know how in the latest version, I can’t check it). If you change the resolution of a file without resampling (as before, some tried to zoom the document in this way), then in this case all smart filters were recalculated. This greatly slowed down the process.
You can change the resolution (without rasampling) to some, and then return it back. All smart filters will be updated (twice).
I think so. Check ....
Copy link to clipboard
Copied
Does this help?
// force redraw of smart filters;
// 2021, use it at your own risk;
if (app.documents.length > 0) {
var theSmartObjects = collectFilteredSmartObjects ();
for (var m = 0; m < theSmartObjects.length; m++) {
var desc10 = new ActionDescriptor();
var ref6 = new ActionReference();
ref6.putIdentifier( charIDToTypeID( "Lyr " ), theSmartObjects[m][1] );
desc10.putReference( charIDToTypeID( "null" ), ref6 );
desc10.putEnumerated(charIDToTypeID( "FTcs" ), charIDToTypeID( "QCSt" ), charIDToTypeID( "Qcsa" ));
var idOfst = charIDToTypeID( "Ofst" );
var desc11 = new ActionDescriptor();
var idPxl = charIDToTypeID( "#Pxl" );
desc11.putUnitDouble( charIDToTypeID( "Hrzn" ), idPxl, 0 );
desc11.putUnitDouble( charIDToTypeID( "Vrtc" ), idPxl, 0 );
desc10.putObject( idOfst, idOfst, desc11 );
executeAction( charIDToTypeID( "Trnf" ), desc10, DialogModes.NO );
};
};
////////////////////////////////////
////// collect smart objects with a smart filter, probably based on code by paul, mike or x //////
function collectFilteredSmartObjects () {
// the file;
var myDocument = app.activeDocument;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
if(layerDesc.hasKey(stringIDToTypeID('smartObject'))) {
var soDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObject'));
// check if smart object has a smart filter;
if (soDesc.hasKey(stringIDToTypeID('filterFX')) == true) {theLayers.push([theName, theID])};
}
};
}
catch (e) {};
};
return theLayers
};