Copy link to clipboard
Copied
Layers structure:
Each of these Smart Objects has it's own LayerComps with names similar to the layer name:
I need to switch on each of the Smart Objects in the LayerSet "Element" one by one and apply the specified LayerComp at the same time. E.g. "Element Red" got "Red" LayerComp applied, "Element Yellow" - "Yellow", etc.
What I have for now.
I've modified a bit Michael L Halecode posted here to switch layers one by one. It's all looks like that:
var DBG = 1;
var id = getSelectedLayerID();
var name = getLayerNameByID(id);
var variations = ["Red", "Yellow", "Green", "Blue"];
if(DBG) {alert("id="+id+"; name="+name); };
for( i=0; i<variations.length; i++ ) {
layerName = name+" "+variations;
showSetByOne( layerName, name );
if(DBG) {alert(layerName)};
}
function showSetByOne( layerName, groupName ){
var setFolder = app.activeDocument.activeLayer;
if (setFolder.typename == 'LayerSet' && setFolder.name == groupName ) {
for( var setIndex = 0; setIndex<setFolder.layers.length; setIndex++) {
if(setFolder.layers[setIndex].name == layerName){
setFolder.layers[setIndex].visible = true;
switchPlacedLayerComp(setFolder.layers[setIndex].id, 1402355601); //exact ID of one of the LayerComps got from ScriptListener
}else{
setFolder.layers[setIndex].visible = false;
}
}
}
}
function switchPlacedLayerComp(id, compID) {
// (ref = new ActionReference()).putEnumerated(sTT('layer'), sTT('ordinal'), sTT('targetEnum'));
(ref = new ActionReference()).putIdentifier( sTT("layer"), id );
// (ref = new ActionReference()).putIndex( sTT("layer"), id );
(desc = new ActionDescriptor()).putReference( sTT("null"), ref );
// alert("Inside Func: "+id);
desc.putInteger( sTT("compID"), compID );
// desc.putString( sTT("comp"), "Red" );
executeAction( sTT("setPlacedLayerComp"), desc, DialogModes.NO );
}
But I can not find any way to process the Smart Objects Layer Comps applying. If to select the exact SO layer and use the exact "compID" ( 1402355601) that was got from Script Listener then LayerComp applies to. But I have only LayerComps names but not IDs. And I could not apply LayerComp to SmartObject without selecting it. Neither by SmarObject id nor by name.
Kukurykus it seems I could not solve this puzzle without your help
Thanks to all for help in advance!
At the bottom you find script that should work. As you understand I can not test it as following part was not yet part of CS6:
(ref2 = new ActionReference()).putEnumerated(sTT('layer'),
sTT('ordinal'), sTT('targetEnum')); (dsc3 = new ActionDescriptor())
.putReference(sTT('null'), ref2), dsc3.putInteger(sTT('compID'), compID)
executeAction(sTT('setPlacedLayerComp'), dsc3, DialogModes.NO)
Anyway to see that works - for both files you sent - I alerted compID instead of above code nested in script you fi
...Copy link to clipboard
Copied
Great work. The code running well in CC2015.5 but I can't make it works in CC2015. For license reason I only able use CC2015 for my work. Do you have working code for CC2015?
Copy link to clipboard
Copied
With this, you can get smart object comps of all smart objects in document with IDs and names without opening them
var docRef = new ActionReference();
var desc = new ActionDescriptor();
var JSONid = stringIDToTypeID("json");
docRef.putProperty(charIDToTypeID('Prpr'), JSONid);
docRef.putEnumerated(stringIDToTypeID("document"), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
desc.putReference(charIDToTypeID('null'), docRef);
desc.putBoolean(stringIDToTypeID("compInfo"), false); // just return the Layer Comp settings
desc.putBoolean(stringIDToTypeID( "expandSmartObjects" ), true); // return Layer Comp settings for each layer
desc.putBoolean(stringIDToTypeID( "getCompLayerSettings" ), false); // return Layer Comp settings for each layer
var result = executeAction(charIDToTypeID( "getd" ), desc, DialogModes.NO).getString(JSONid);
objectFromJSONString > placed > (item) > comps
This is code for generator plugin. Will work by default in modern Photoshop.
smartObjectMore property work properly in CC2015.5 and higher.
In lower version you have only "smartObject" property with less info.
Copy link to clipboard
Copied
Kukurykus, sorry man, was a bit out of PC.
Here is the code:
while(tSID(dsc1.getEnumerationValue(sTID(lS = 'layerSection'))) != lS + 'End') {
(ref1 = new ActionReference()).putIndex(sTID('layer'), j--)
(dsc1 = executeActionGet(ref1)).putReference(sTID('null'), ref1), dsc1.putBoolean(sTID('makeVisible'), false)
executeAction(sTID('select'), dsc1, no = DialogModes.NO)
lsop = (function getSelectedLinkedSOpath() {
try {
(ref9 = new ActionReference()).putEnumerated(sTID('layer'), sTID('ordinal'), sTID('targetEnum'))
var layerDesc = executeActionGet(ref9)
var soDesc = layerDesc.getObjectValue(sTID('smartObject'))
var localFilePath = soDesc.getPath(sTID('link'))
} catch(e) {}
return localFilePath
});
if (nme = dsc1.getString(sTID('name')).match(/\w+$/)) {
(function bin(){
isEmbed = ( psbPath=='~/desktop/.psb' ) ? true : false
(fle = File( psbPath )).encoding = 'binary'
if(isEmbed) {
(dsc2 = new ActionDescriptor()).putPath(sTID('null'), fle);
executeAction(sTID('placedLayerExportContents'), dsc2, no);
} fle.open('r'); var r = fle.read();
length = nme[0].length * 2, reg = 'Nm TEXT.{4}.{0,' + length + '}.{6}compIDlong.{4}'; var m = r.match(RegExp(reg, 'g'))
for(i=0; i < m.length;) {
if (RegExp(nme).test(m[i++].slice(12, -20).match(/[^\x00]/g).join(''))) {
compID = eval('0x' + m[--i].slice(-4).replace(/./g, function(v) {return v.charCodeAt().toString(16)})); break
}
} fle.close(); if(isEmbed){fle.remove()}
(ref2 = new ActionReference()).putEnumerated(sTID('layer'), sTID('ordinal'), sTID('targetEnum'))
(dsc3 = new ActionDescriptor()).putReference(sTID('null'), ref2), dsc3.putInteger(sTID('compID'), compID)
executeAction(sTID('setPlacedLayerComp'), dsc3, DialogModes.NO)
})( psbPath = ( undefined==(psbPath=lsop()) ? '~/desktop/.psb' : psbPath ))
}
}
Copy link to clipboard
Copied
You seem to be very smart if you knew how to modifiy that code I wrote (which even for me was hard while creating it, especially first time of this kind), and then combine it with parts given by r-bin. That's very usefull. Thanks for posting!
Still you did not answer for my question about spaces in reply no. 14 of this theard. I wonder was I close of point you did.
Copy link to clipboard
Copied
Hi Kukurykus
It seems that I've confused you with that "spaces" issue
Yes, you was close and it works. But I did not explain correctly what I need.
In general, I had an idea to make layer name to consist from two parts separated with some kind of separator ("@" in that case).
One part is the layer name itself and the other is the part that has to be compared with the layer comp name. E.g. "Element @Red" - where "Element" is the first part and "@Red" is the other to be compared.
So, if going with the simple words then the script works with your implementation as well ("Element @Red"). But if the second part consits of two or more words then of course it does not ("Element @Red with Yellow"). As a solution I've decided just to use simple words or join them with a underscore if more complex.
Best regards
Copy link to clipboard
Copied
Thx, that what I wanted to know, as your earlier description about was inconsistent. Well that is possible to do, I know how, but I see you found you can fit your work to code, not vice versa. When one day I have nothing to do I can write it though