Skip to main content
DrPepperJo
Participant
November 25, 2021
Question

Force re-rendering of smart filters

  • November 25, 2021
  • 2 replies
  • 943 views

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?

 

This topic has been closed for replies.

2 replies

Legend
November 26, 2021

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);

 

DrPepperJo
Participant
November 26, 2021

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.

c.pfaffenbichler
Community Expert
Community Expert
November 27, 2021

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
};
c.pfaffenbichler
Community Expert
Community Expert
November 26, 2021

cmd-T, enter would seem like an option, doubleclicking any Smart Filter and hitting OK another. 

DrPepperJo
Participant
November 26, 2021

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.