@Tyler229371107i00
The following script will apply the last used liquify mesh to all layers and layer masks in a single pass!
/*
Liquify Selected Layers & Masks using Last Mesh.jsx
v1.0, 8th January 2024, Stephen Marsh
*/
#target photoshop
function main() {
// Save the current dialog display settings
var savedDisplayDialogs = app.displayDialogs;
app.displayDialogs = DialogModes.NO;
// Capture the initial layer visibility and layer selection
var currentLayersState = getLayersVisiblity();
// Get the selected layers: courtesy of jazz-y
var s2t = stringIDToTypeID;
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('targetLayersIDs'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var lrs = executeActionGet(r).getList(p),
sel = new ActionReference();
// Loop over the selected layers: courtesy of jazz-y
for (var i = 0; i < lrs.count; i++) {
sel.putIdentifier(s2t('layer'), p = lrs.getReference(i).getIdentifier(s2t('layerID')));
(r = new ActionReference()).putIdentifier(s2t('layer'), p);
(d = new ActionDescriptor()).putReference(s2t("target"), r);
executeAction(s2t('select'), d, DialogModes.NO);
// Raster mask, vector mask not currently supported
if (hasLayerMask() === true) {
// Apply the last liquify filter mesh to the layer mask
selectLayerCompositeChannel("mask");
applyLastMesh();
} else {
// Apply the last liquify filter mesh
applyLastMesh();
}
}
// Finish the loop
// Restore the initial layer visibility and selection
setLayersVisiblity(currentLayersState);
// Restore the dialogs
app.displayDialogs = savedDisplayDialogs;
app.beep();
alert("Script completed!");
}
// Single history stage undo
activeDocument.suspendHistory("Liquify Selected Layers & Masks using Last Mesh.jsx", "main()");
///// FUNCTIONS /////
function hasLayerMask() {
// From Adobe's Flatten All Masks.jsx
var hasLayerMask = false;
try {
var ref = new ActionReference();
var keyUserMaskEnabled = app.charIDToTypeID('UsrM');
ref.putProperty(app.charIDToTypeID('Prpr'), keyUserMaskEnabled);
ref.putEnumerated(app.charIDToTypeID('Lyr '), app.charIDToTypeID('Ordn'), app.charIDToTypeID('Trgt'));
var desc = executeActionGet(ref);
if (desc.hasKey(keyUserMaskEnabled)) {
hasLayerMask = true;
}
} catch (e) {
hasLayerMask = false;
}
return hasLayerMask;
}
function selectLayerCompositeChannel(chanPara) {
// "RGB" | "mask"
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated(s2t("channel"), s2t("channel"), s2t(chanPara));
descriptor.putReference(s2t("null"), reference);
descriptor.putBoolean(s2t("makeVisible"), false);
executeAction(s2t("select"), descriptor, DialogModes.NO);
}
function getLayersVisiblity() {
// by jazz-y
var s2t = stringIDToTypeID,
t2s = typeIDToStringID;
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('targetLayersIDs'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var targetLayers = executeActionGet(r).getList(p),
seletion = [],
visiblity = {};
for (var i = 0; i < targetLayers.count; i++) seletion.push(targetLayers.getReference(i).getIdentifier());
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('numberOfLayers'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var len = executeActionGet(r).getInteger(p);
for (var i = 1; i <= len; i++) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerSection'));
r.putIndex(s2t('layer'), i);
if (t2s(executeActionGet(r).getEnumerationValue(p)) == 'layerSectionEnd') continue;
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerID'));
r.putIndex(s2t('layer'), i);
var id = executeActionGet(r).getInteger(p);
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('visible'));
r.putIndex(s2t('layer'), i);
var visible = executeActionGet(r).getBoolean(p);
visiblity[id] = visible;
}
return {
selection: seletion,
visiblity: visiblity
};
}
function setLayersVisiblity(layersStateObject) {
// by jazz-y
var s2t = stringIDToTypeID;
for (var a in layersStateObject.visiblity) {
makeVisible = layersStateObject.visiblity[a] ? "show" : "hide";
(r = new ActionReference()).putIdentifier(s2t('layer'), a);
(d = new ActionDescriptor()).putReference(s2t('target'), r);
executeAction(s2t(makeVisible), d, DialogModes.NO);
}
if (layersStateObject.selection.length) {
var r = new ActionReference();
for (var i = 0; i < layersStateObject.selection.length; i++)
r.putIdentifier(s2t("layer"), layersStateObject.selection[i]);
(d = new ActionDescriptor()).putReference(s2t("target"), r);
d.putBoolean(s2t("makeVisible"), false);
executeAction(s2t("select"), d, DialogModes.NO);
} else {
(r = new ActionReference()).putEnumerated(s2t("layer"), s2t('ordinal'), s2t('targetEnum'));
(d = new ActionDescriptor()).putReference(s2t('target'), r);
executeAction(s2t('selectNoLayers'), d, DialogModes.NO);
}
}
function applyLastMesh() {
var idLqFy = charIDToTypeID("LqFy");
var desc213 = new ActionDescriptor();
var idLqMD = charIDToTypeID("LqMD");
desc213.putString(idLqMD, app.preferencesFolder.fsName + "/" + "Liquify Last Mesh.psp");
executeAction(idLqFy, desc213, DialogModes.NO);
}