Copy link to clipboard
Copied
Hello all,
I'm facing unusual problem currently. In CC 2014 it's now possible to switch right in main document layer comps of placed files (smart objects or linked).
Properties panel shows layer comp names of those smart objects.
But... I looked into scriptListener code and switching of layer comps in child files is done through compID. But if you want to switch layer comp in the opened file (edit contents), it is performed with layer comp name.
I need to be able to pass layer comp id from parent file to opened child file, and switch layer comp accordingly.
so, 2 questions:
1) Is it possible to switch layer comp in document by layer comp ID somehow?
2) Is it possible to get layer comp name, if you know layer comp ID (and vice versa)?
I know this information is inside image resource block in .psd file, but parsing .psd with script would be an overhead. I tried to do it with plugin, but no success yet - can't get this data inside filter plugin...
thanks!
Copy link to clipboard
Copied
Looks like this is another feature that it has not been deemed worthwhile to provide (reasonably convenient) Scripting support for. (edited)
And quite frankly apart from the likely performance issues I wouldn’t even know how to go about "parsing .psd" …
Maybe you should post a Feature Request for improved Scripting access to the feature over at
Copy link to clipboard
Copied
I have switched to generator api, there is all relevant data in document info.
there's info on getting data passed from extend script to generator, but I haven't seen how to make it vice versa. calling generator from extend script is described, but getting data from generator to extend script is not
Copy link to clipboard
Copied
there's info on getting data passed from extend script to generator
Could you please post a link to that info?
Copy link to clipboard
Copied
Calling Generator Plugins from ExtendScript · adobe-photoshop/generator-core Wiki · GitHub
the funniest thing is that my plugin doesn't work with built-in generator anyway, only with external developer version (probably built-in is too old)
Copy link to clipboard
Copied
This is still a thing... I found what I *think* should be the layer comp info through the Action Manager descriptors, but it returns -1 no matter what comp is applied. I definitely have a linked smart object with a layer comp set.
// get application description object
var actref = new ActionReference();
actref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var appDesc = executeActionGet(actref);
// get layer count from app description
var layerCount = appDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process layers
for (var l = 0; l <= layerCount; l++) {
try {
actref = new ActionReference();
actref.putIndex( charIDToTypeID( "Lyr " ), l)
layerDesc = executeActionGet(actref)
isSmartObject = layerDesc.hasKey(stringIDToTypeID('smartObject'))
if(isSmartObject)
{
// get object descriptors
var soDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObject'))
// var placedDesc = soDesc.getEnumerationValue(stringIDToTypeID('placed'))
var compsDesc = soDesc.getObjectValue(stringIDToTypeID('compsList'))
var name = layerDesc.getString(stringIDToTypeID('name'))
var id = layerDesc.getInteger(stringIDToTypeID('layerID'))
var fileReference = soDesc.getString(stringIDToTypeID("fileReference"))
var compID = compsDesc.getInteger(stringIDToTypeID('compID'))
var originalCompID = compsDesc.getInteger(stringIDToTypeID('originalCompID'))
$.writeln ("compID: " + compID);
$.writeln ("originalCompID: " + originalCompID);
}
}
}
prints:
compID: -1
originalCompID: -1
But if I hook up generator.getDocumentInfo, I get this back:
{
"id": 19,
"index": 3,
"type": "layer",
"name": "raster blue",
"bounds": {
"top": 251,
"left": 112,
"bottom": 353,
"right": 302
},
"visible": true,
"clipped": false,
"generatorSettings": false,
"smartObject": {
"ID": "1f863200-620b-11e5-88ac-a70971fb3c91",
"placed": "472d38d4-620b-11e5-88ac-a70971fb3c91",
"antiAliasType": 16,
"type": 2,
"transform": [
112,
251,
302,
251,
302,
353,
112,
353
],
"comp": 1024141590
}
},
So maybe it's a bug with the "compsList" ActionDescriptor object not being updated properly?
Copy link to clipboard
Copied
So, I figured it out... generator turned out to be a wild goose chase because the schema it prints for a document isn't the same schema that is used by ActionDescriptors. I figured out how to create a function that would print out all the keys in a descriptor:
then using this I was able to start inspecting wtf the real schema was.
function printKeysFromActionDesc( atnDesc )
{
for( var i=0; i<atnDesc.count; i++ ){
var key = atnDesc.getKey(i);
$.writeln( typeIDToStringID(key) );
}
}
the value of the currently selected layer comp on a smart object is under "smartObjectMore" > "comp"
here's some of Max's code modified:
// get application description object
var actref1 = new ActionReference();
actref1.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var appDesc = executeActionGet(actref1);
// get layer count from app description
var layerCount = appDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process layers
for (var l = 0; l <= layerCount; l++) {
var actref2 = new ActionReference();
actref2.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
actref2.putIndex( charIDToTypeID( "Lyr " ), l);
var layerDesc;
try{ layerDesc = executeActionGet(actref2); }
catch(e){ continue; }
var isSmartObject = layerDesc.hasKey(stringIDToTypeID('smartObject'));
if(isSmartObject)
{
// get object descriptors
var soDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObject'));
var soMoreDesc = layerDesc.getObjectValue(stringIDToTypeID('smartObjectMore'));
var compsDesc = soDesc.getObjectValue(stringIDToTypeID('compsList'));
var compList = compsDesc.getList(stringIDToTypeID('compList'));
var compObjDesc = compList.getObjectValue(2);
$.writeln ( "name: " + compObjDesc.getString(stringIDToTypeID('name')) );
$.writeln ( "id: " + compObjDesc.getInteger(stringIDToTypeID('ID')) );
$.writeln ( "comp: " + soMoreDesc.getInteger(stringIDToTypeID('comp')) );
}
}
Within that code block, you can see getting a layer's comp and a list of all possible comps in "compList". (NOTE: "compList" is inside "compsList")
I also suspect that within "smartObjectMore", you can get the same data as "compsList" under "compInfo"
So, I think I can answer the 2 original questions in this thread now:
1) Is it possible to switch layer comp in document by layer comp ID somehow?
Yes, if you install the ScriptListener photoshop plugin, you can see the code required to do this which looks something like:
var idsetPlacedLayerComp = stringIDToTypeID( "setPlacedLayerComp" );
var desc11 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref9 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref9.putEnumerated( idLyr, idOrdn, idTrgt );
desc11.putReference( idnull, ref9 );
var idcompID = stringIDToTypeID( "compID" );
desc11.putInteger( idcompID, 1770071028 );
executeAction( idsetPlacedLayerComp, desc11, DialogModes.NO );
I haven't tried this myself, but I'm guessing that this code is implying that a null value means that the compID will be applied to the selected layer.
2) Is it possible to get layer comp name, if you know layer comp ID (and vice versa)?
yep, if you pull the compList as in my earlier example, you'll have an array of all the layer comps including "name" and "ID" which should give you what you need to lookup either one.
Copy link to clipboard
Copied
You, sir, deserve a medal.
Copy link to clipboard
Copied
var idsetPlacedLayerComp = stringIDToTypeID( "setPlacedLayerComp" );
well, it's not switching layer comp in main file, it's switching layer comp in placed file. see the difference? I have mentioned it in my original post, quoting it again:
switching of layer comps in child files is done through compID. But if you want to switch layer comp in the opened file (edit contents), it is performed with layer comp name
Copy link to clipboard
Copied
Ah, my bad, here's my listener output for changing the layer comp for a document:
var idapplyComp = stringIDToTypeID( "applyComp" );
var desc37 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref32 = new ActionReference();
var idcompsClass = stringIDToTypeID( "compsClass" );
ref32.putName( idcompsClass, "water" );
desc37.putReference( idnull, ref32 );
executeAction( idapplyComp, desc37, DialogModes.NO );
and if this document is a smart object within a parent document, you might be able to use the fileReference variable from Max's example to open it... or you could probably use something to this effect:
var idplacedLayerEditContents = stringIDToTypeID( "placedLayerEditContents" );
var desc42 = new ActionDescriptor();
executeAction( idplacedLayerEditContents, desc42, DialogModes.NO );
Copy link to clipboard
Copied
this is exactly what I wrote about in first post
I looked into scriptListener code and switching of layer comps in child files is done through compID. But if you want to switch layer comp in the opened file (edit contents), it is performed with layer comp name.
ref32.putName( idcompsClass, "water" );
comp name is used here, not compID.
Copy link to clipboard
Copied
And if you look at my original response: "if you pull the compList as in my earlier example, you'll have an array of all the layer comps including "name" and "ID" which should give you what you need to lookup either one"
Copy link to clipboard
Copied
ok. it was 3 years ago, I'll check it once I have the need again - cheers!
Copy link to clipboard
Copied
Hello Actionsketch
Sorry to hijack this thread, but after a long time researching the forum, this thread is the closest i could get to possibly answer my questions.
I opened a thread for this snd it would be awesome if you could join and maybe help out with some of your great skills.
Select Layers in Smartobject sequentialy and save Mainfile each time
Basically i need this:
Thanks a lot for any help as i'm stuck with this.
Daniel