Skip to main content
ajabon grinsmith
Community Expert
Community Expert
November 19, 2021
質問

Can you make a selection that fills in a "U" type path?

  • November 19, 2021
  • 返信数 4.
  • 2006 ビュー

Hi, there

I want to make a selection like the one shown in the figure from a pathItem of type "U".
It can be either A or B.

 

 

Scripting has limited my ability.
- I deleted two pathPoints but did not get two subPathItems. I can only get one of them.
- I tried to delete a pathPoints that interfered with the makeSelection. It was not possible to delete any pathPoint or make it selected for that purpose.

 

As a last resort, I'm thinking of getting an array of coordinates of only the pathPoints I need and make a selection. However, this would probably be very time consuming.

 

I need some ideas.
Thanks in advance.

 

Translated with [Link removed by moderator] (free version)

このトピックへの返信は締め切られました。

返信数 4

Leslie Moak Murray
Community Expert
Community Expert
December 2, 2021

Can't you just go Edit>Define Custom Shape, and then you'll have the paths?

ajabon grinsmith
Community Expert
Community Expert
December 2, 2021

It is possible, but it did not involve fulfilling my purpose.
By the way, I just finished the function!

Legend
December 2, 2021

Here is a four-point path. Draw a selection you want to get and explain what it is for.

 

ajabon grinsmith
Community Expert
Community Expert
December 2, 2021

In my case, there are no such ambiguous shapes. I use only uniformed lines.

I will complete the function of the script soon.

c.pfaffenbichler
Community Expert
Community Expert
November 20, 2021

The code below would destroy Work Paths, but as long as all Paths are saved it should work here. 

One needs to manually select the points-to-be-removed and a temporary Path without those is created and a Selection created from that. (the gif should illustrate)

// create selection from added subpathitems after removing selected pathpoints;
// work path would get destroyed;
// 2021, use it at your own risk;
if (app.documents.length > 0) {
if (app.activeDocument.pathItems.length > 0) {
// collect path;
var path1 = collectselectedPathPathInfoFromDesc ();
if (path1.length > 0) {
// delete;
var iddelete = stringIDToTypeID( "delete" );
executeAction( iddelete, undefined, DialogModes.NO );
// collect edited path;
var path2 = collectselectedPathPathInfoFromDesc ();
// undo;
executeAction( charIDToTypeID("undo"), undefined, DialogModes.NO );
if (path2.length > 0) {
if (path1 != path2) {
// change shape operations;
for (var m = 0; m < path2.length; m++) {
path2[m][path2[m].length-1] = 1097098272
};
// create temp path;
var trashThis = createPath2018(path2, "trashThis");
// make selection;
trashThis.makeSelection(0, true, SelectionType.REPLACE);
// remove temp path;
trashThis.remove();
}
}
}
}
};
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
////// create a path from collectPathInfoFromDesc2012-array //////
function createPath2018(theArray, thePathsName) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.POINTS;
// thanks to xbytor;
cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };

    var desc1 = new ActionDescriptor();
    var ref1 = new ActionReference();
    ref1.putProperty(cTID('Path'), cTID('WrPt'));
    desc1.putReference(sTID('null'), ref1);
    var list1 = new ActionList();
    
for (var m = 0; m < theArray.length; m++) {
    var thisSubPath = theArray[m];
    
    var desc2 = new ActionDescriptor();
    desc2.putEnumerated(sTID('shapeOperation'), sTID('shapeOperation'), thisSubPath[thisSubPath.length - 1]);
    var list2 = new ActionList();
    var desc3 = new ActionDescriptor();
    desc3.putBoolean(cTID('Clsp'), thisSubPath[thisSubPath.length - 2]);
    var list3 = new ActionList();
    
for (var n = 0; n < thisSubPath.length - 2; n++) {
    var thisPoint = thisSubPath[n];
    
    var desc4 = new ActionDescriptor();
    var desc5 = new ActionDescriptor();
    desc5.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[0][0]);
    desc5.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[0][1]);
    desc4.putObject(cTID('Anch'), cTID('Pnt '), desc5);
    var desc6 = new ActionDescriptor();
    desc6.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[1][0]);
    desc6.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[1][1]);
    desc4.putObject(cTID('Fwd '), cTID('Pnt '), desc6);
    var desc7 = new ActionDescriptor();
    desc7.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[2][0]);
    desc7.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[2][1]);
    desc4.putObject(cTID('Bwd '), cTID('Pnt '), desc7);
    desc4.putBoolean(cTID('Smoo'), thisPoint[3]);
    list3.putObject(cTID('Pthp'), desc4);
    
    };
    
    desc3.putList(cTID('Pts '), list3);
    list2.putObject(cTID('Sbpl'), desc3);
    desc2.putList(cTID('SbpL'), list2);
    list1.putObject(cTID('PaCm'), desc2);
    };
    
    desc1.putList(cTID('T   '), list1);
    executeAction(cTID('setd'), desc1, DialogModes.NO);

// name work path;
var desc30 = new ActionDescriptor();
var ref6 = new ActionReference();
var idPath = charIDToTypeID( "Path" );
ref6.putClass( idPath );
desc30.putReference( charIDToTypeID( "null" ), ref6 );
var ref7 = new ActionReference();
ref7.putProperty( idPath, charIDToTypeID( "WrPt" ) );
desc30.putReference( charIDToTypeID( "From" ), ref7 );
desc30.putString( charIDToTypeID( "Nm  " ), thePathsName );
executeAction( charIDToTypeID( "Mk  " ), desc30, DialogModes.NO );
/// get index;
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("itemIndex"));
ref.putEnumerated( charIDToTypeID("Path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var pathDesc = executeActionGet(ref);
var myPathItem = activeDocument.pathItems[pathDesc.getInteger(stringIDToTypeID("itemIndex")) - 1];
app.preferences.rulerUnits = originalRulerUnits;
return myPathItem
};
////// collect path info from actiondescriptor, smooth added //////
function collectselectedPathPathInfoFromDesc (){
try {
// get index;
    var ref = new ActionReference();
    ref.putProperty (stringIDToTypeID("property"), stringIDToTypeID("targetPathIndex")); 
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    var docDesc = executeActionGet(ref);
    var theIndex = docDesc.getInteger(stringIDToTypeID("targetPathIndex"))+1;
// collect data;
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.POINTS;
// based of functions from xbytor’s stdlib;
var ref = new ActionReference();
ref.putIndex(cTID("Path"), theIndex);
var desc = app.executeActionGet(ref);
var pname = desc.getString(cTID('PthN'));
// create new array;
var theArray = new Array;
var pathComponents = desc.getObjectValue(cTID("PthC")).getList(sTID('pathComponents'));
// for subpathitems;
for (var m = 0; m < pathComponents.count; m++) {
    var listKey = pathComponents.getObjectValue(m).getList(sTID("subpathListKey"));
    var operation1 = pathComponents.getObjectValue(m).getEnumerationValue(sTID("shapeOperation"));
    switch (operation1) {
        case 1097098272:
        var operation = 1097098272 //cTID('Add ');
        break;
        case 1398961266:
        var operation = 1398961266 //cTID('Sbtr');
        break;
        case 1231975538:
        var operation = 1231975538 //cTID('Intr');
        break;
        default:
//		case 1102:
        var operation = sTID('xor') //ShapeOperation.SHAPEXOR;
        break;
        };
// for subpathitem’s count;
    for (var n = 0; n < listKey.count; n++) {
        theArray.push(new Array);
        var points = listKey.getObjectValue(n).getList(sTID('points'));
        try {var closed = listKey.getObjectValue(n).getBoolean(sTID("closedSubpath"))}
        catch (e) {var closed = false};
// for subpathitem’s segment’s number of points;
        for (var o = 0; o < points.count; o++) {
            var anchorObj = points.getObjectValue(o).getObjectValue(sTID("anchor"));
            var anchor = [anchorObj.getUnitDoubleValue(sTID('horizontal')), anchorObj.getUnitDoubleValue(sTID('vertical'))];
            var thisPoint = [anchor];
            try {
                var left = points.getObjectValue(o).getObjectValue(cTID("Fwd "));
                var leftDirection = [left.getUnitDoubleValue(sTID('horizontal')), left.getUnitDoubleValue(sTID('vertical'))];
                thisPoint.push(leftDirection)
                }
            catch (e) {
                thisPoint.push(anchor)
                };
            try {
                var right = points.getObjectValue(o).getObjectValue(cTID("Bwd "));
                var rightDirection = [right.getUnitDoubleValue(sTID('horizontal')), right.getUnitDoubleValue(sTID('vertical'))];
                thisPoint.push(rightDirection)
                }
            catch (e) {
                thisPoint.push(anchor)
                };
            try {
                var smoothOr = points.getObjectValue(o).getBoolean(cTID("Smoo"));
                thisPoint.push(smoothOr)
                }
            catch (e) {thisPoint.push(false)};
            theArray[theArray.length - 1].push(thisPoint);
            };
        theArray[theArray.length - 1].push(closed);
        theArray[theArray.length - 1].push(operation);
        };
    };
// by xbytor, thanks to him;
function cTID (s) { return cTID[s] || cTID[s] = app.charIDToTypeID(s); };
function sTID (s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); };
// reset;
app.preferences.rulerUnits = originalRulerUnits;
return theArray;
} catch (e) {
return undefined
}
};

 

ajabon grinsmith
Community Expert
Community Expert
December 1, 2021

c.pfaffenbichler, 

I'm sorry for the delay in responding. Thank you, that's great technology.
Unfortunately, I can't force the user to choose a point this time. This time the client is not too familiar with photoshop.
A big thank you for your effort and knowledge.

c.pfaffenbichler
Community Expert
Community Expert
December 1, 2021

Determining the »depression«/»bay« in a subPathItem automatically would seem cumbersome, but not impossible. 

Simply using the two highest points would not work reliably because both might be on the same »arm«.

And could there ever be »W«-shapes that have two (or more) »depressions«? 

JJMack
Community Expert
Community Expert
November 19, 2021

The  image you posted shows vector Paths not selections.  You can convert the Paths to selections an file the selections with pixels you could also add a solid fill layer and mask  the fill layer with your  vector paths. A script can easily do those operations. Adobe Photoshop  Scripting DOM does not cover all of Photoshop features some times you need to use Action manager code in Photoshop scripts.   But in this case you can set an active selection the has a U shape with DOM code. You are not required to create vector U shape closed paths. You can make selection like  your White Areas A and B with a script.  You can not EDIT Paths in Photoshop you would need to copy the path  to an array modify the points you want to edit then create a new path  the path you want.

 

I do not have the Math knowledge to do curves in paths.  Strright point to point selections is more my speed.

JJMack
ajabon grinsmith
Community Expert
Community Expert
November 19, 2021

Hi JJMack, thanks for the response.

The image I posted is just a quick mask, that's my ideal selection. Sorry for the confusion.

First, I have a path item that I called "Original".
I want to make a selection based on this, which can be either A or B, as shown by the white area.

Regards.

ajabon grinsmith
Community Expert
Community Expert
November 19, 2021

The paths overlapping Selection A and B were placed by me after the fact, to give an idea of how my ideal selection relates to the shape of the path items.

 

In order to do this in the script, I thinking I need to remove the inner pathpoints.
I know which pathpoints I need to delete, but I don't know how to delete them.
If I could select any pathpoint, I could delete it, but I can't even select it.

 

If there is a concrete way to do this that is in line with my idea, I would appreciate it.
Of course, other methods would also be very helpful. However, it needs to be an automatic process.