Copy link to clipboard
Copied
Hello. I have been wanting to implement one idea for a long time, but my knowledge is too small for that. I need to flip the coordinates of the transformation points of the smart object. I've sketched out a diagram for clarity:
it is possible without a pop-up window. I showed this for an example. You can even just follow one x-axis. Any result would be useful to me. I managed to find topics similar in meaning, but this is not exactly what you need.
There is a script that reads the coordinates of a smart object in Get Layer Transform X Y Top Left Coordinate Position, but it does not process them. Perhaps it could be improved somehow. Thank you in advance
Copy link to clipboard
Copied
Make a new copy of the Smart Object.
Make Flip-Horizontal transform to the smart object.
Inside the Smart Object also do Flip-Horizontal transform.
So it fits?
Copy link to clipboard
Copied
Yes, thank you. I know about this method, but then you need to flip the contents of the smart object every time. When I make a project for a client, this method is not suitable. It is very tedious to explain everything to them every time
Copy link to clipboard
Copied
There is a script like this (thanks to r-bin), but I can't figure out exactly how to write data into it. How to find out which sequence of points.
change_one_warp_mesh_point_for_smart_object(2, 100,150);
function change_one_warp_mesh_point_for_smart_object(point_index, hor,ver)
{
try {
var r = new ActionReference();
r.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("smartObjectMore"));
r.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var obj = executeActionGet(r).getObjectValue(stringIDToTypeID("smartObjectMore")) ;
var warp = obj.getObjectValue(stringIDToTypeID("warp"));
// if there is no warp, we will not create a new one,
// since we need to specify 4x4 points for this, and we want to change only one
if (!warp.hasKey(stringIDToTypeID("customEnvelopeWarp"))) return false;
/////////////// changing one point in the current warp mesh ////////////////////
var meshPoints = warp.getObjectValue(stringIDToTypeID("customEnvelopeWarp")).getList(stringIDToTypeID("meshPoints"));
var new_meshPoints = new ActionList();
for (var i = 0; i < meshPoints.count; i++)
{
if (i != point_index)
{
new_meshPoints.putObject(stringIDToTypeID("rationalPoint"), meshPoints.getObjectValue(i));
}
else
{
var d = new ActionDescriptor();
d.putUnitDouble(stringIDToTypeID("horizontal"), stringIDToTypeID("pixelsUnit"), hor);
d.putUnitDouble(stringIDToTypeID("vertical"), stringIDToTypeID("pixelsUnit"), ver);
new_meshPoints.putObject(stringIDToTypeID("rationalPoint"), d);
}
}
var customEnvelopeWarp = new ActionDescriptor();
customEnvelopeWarp.putList(stringIDToTypeID("meshPoints"), new_meshPoints);
warp.putObject(stringIDToTypeID("customEnvelopeWarp"), stringIDToTypeID("customEnvelopeWarp"), customEnvelopeWarp);
///////////////////////////////////////////////////////////////////////////////
// execute transform command
var d = new ActionDescriptor();
d.putEnumerated(stringIDToTypeID("freeTransformCenterState"), stringIDToTypeID("quadCenterState"), stringIDToTypeID("QCSAverage"));
d.putObject(stringIDToTypeID("warp"), stringIDToTypeID("warp"), warp);
executeAction(stringIDToTypeID("transform"), d, DialogModes.NO);
}
catch (e) { alert(e); }
}
For example, through the Alchemist plugin, I can see the coordinates of these points. Maybe I should write them manually but swap them?
Copy link to clipboard
Copied
Warp transformation can be very different and complex.
For the simplest (classic customEnvelopeWarp 4x4) of 16 points, I can offer this option.
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("smartObjectMore"));
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var obj = executeActionGet(r).getObjectValue(stringIDToTypeID("smartObjectMore")) ;
var warp = obj.getObjectValue(stringIDToTypeID("warp"));
var meshPoints = warp.getObjectValue(stringIDToTypeID("customEnvelopeWarp")).getList(stringIDToTypeID("meshPoints"));
var p = new Array(); // mesh points array
var max_x;
var min_x;
for (var i = 0; i < meshPoints.count; i++)
{
var x = meshPoints.getObjectValue(i).getUnitDoubleValue(stringIDToTypeID("horizontal"));
var y = meshPoints.getObjectValue(i).getUnitDoubleValue(stringIDToTypeID("vertical"));
if (max_x == undefined || max_x < x) max_x = x;
if (min_x == undefined || min_x > x) min_x = x;
p.push([x,y]);
}
var x0 = (max_x+min_x)/2; // center point
for (var i = 0; i < p.length; i++)
{
p[i][0] = 2*x0 - p[i][0]; // horizontal flip relatively x0
}
function swap(a,b) { var tmp = p[a]; p[a] = p[b]; p[b] = tmp; }
swap(0, 3);
swap(1, 2);
swap(4, 7);
swap(5, 6);
swap(8, 11);
swap(9, 10);
swap(12, 15);
swap(13, 14);
var new_meshPoints = new ActionList();
for (var i = 0; i < p.length; i++)
{
var d = new ActionDescriptor();
d.putUnitDouble(stringIDToTypeID("horizontal"), stringIDToTypeID("pixelsUnit"), p[i][0]);
d.putUnitDouble(stringIDToTypeID("vertical"), stringIDToTypeID("pixelsUnit"), p[i][1]);
new_meshPoints.putObject(stringIDToTypeID("rationalPoint"), d);
}
var customEnvelopeWarp = new ActionDescriptor();
customEnvelopeWarp.putList(stringIDToTypeID("meshPoints"), new_meshPoints);
warp.putObject(stringIDToTypeID("customEnvelopeWarp"), stringIDToTypeID("customEnvelopeWarp"), customEnvelopeWarp);
var d = new ActionDescriptor();
d.putEnumerated(stringIDToTypeID("freeTransformCenterState"), stringIDToTypeID("quadCenterState"), stringIDToTypeID("QCSAverage"));
d.putObject(stringIDToTypeID("warp"), stringIDToTypeID("warp"), warp);
executeAction(stringIDToTypeID("transform"), d, DialogModes.NO);
Checked, works.
Copy link to clipboard
Copied
Yes, it works great, thank you so much! But it would be ideal if the transformation points were still taken into account. Sorry for the impertinence. I'm willing to pay you. If you can finalize the script, then I will be happy! Or you can make 2 different ones
Find more inspiration, events, and resources on the new Adobe Community
Explore Now