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

Adobe Community Professional ,
Nov 18, 2021 Nov 18, 2021

Copy link to clipboard

Copied

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.

 

スクリーンショット 2021-11-19 13.49.20.png

 

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)

TOPICS
Actions and scripting

Views

214

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Nov 18, 2021 Nov 18, 2021

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Nov 18, 2021 Nov 18, 2021

Copy link to clipboard

Copied

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.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Nov 18, 2021 Nov 18, 2021

Copy link to clipboard

Copied

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.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Nov 19, 2021 Nov 19, 2021

Copy link to clipboard

Copied

From your Paths you can get the X Y of each control point and use then fot setting  selection area  create the array  for the area you want to select. Like you do using the poly lasso tool.

Select region  A then  Add to the selection region B

image.png

image.png

JJMack

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Nov 19, 2021 Nov 19, 2021

Copy link to clipboard

Copied

JJMack,

Thanks, I'll evaluate it.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Dec 01, 2021 Dec 01, 2021

Copy link to clipboard

Copied

many thanks JJMack. this post is very informative.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Nov 20, 2021 Nov 20, 2021

Copy link to clipboard

Copied

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)

selectionFromPathMinusSelectedPointsScr.gif

// 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
}
};

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Nov 30, 2021 Nov 30, 2021

Copy link to clipboard

Copied

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.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Nov 30, 2021 Nov 30, 2021

Copy link to clipboard

Copied

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«? 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 01, 2021 Dec 01, 2021

Copy link to clipboard

Copied

Thank you. I'll post an example of a form that is similar to the implemented data.

In fact, it is formed by more than 6,000 pass points. The image has no anch aliasing.

 

スクリーンショット 2021-12-01 19.45.05.png
It is said to be a curve representing time and distance.
I am driven by the need to block off the top and bottom of this shape.
This sub-path was created from a selection, as I thought that path items would be better suited for this kind of work than pixels.
Essentially, it would be great if we could accomplish our goal with just the color information and pixels of the selection.

In the future, I plan to look at the positions of the points of the path in turn, and create a function to connect two points where the path is going in opposite directions.

 

Translated with www.DeepL.com/Translator (free version)

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 01, 2021 Dec 01, 2021

Copy link to clipboard

Copied

What result should that path yield? 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 01, 2021 Dec 01, 2021

Copy link to clipboard

Copied

Ultimately, what I want is a pixels selection. The path is just a means to that end.
Duplicate the background layer with the selection blocking the bay.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 01, 2021 Dec 01, 2021

Copy link to clipboard

Copied

What result do you want in this case? Please post a screenshot or sketch? 

Originally you spoke of »U«-shapes, this shape is very much different … 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 01, 2021 Dec 01, 2021

Copy link to clipboard

Copied

This, this, something else? 

a1.jpga2.jpg

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 01, 2021 Dec 01, 2021

Copy link to clipboard

Copied

vertical one. 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 01, 2021 Dec 01, 2021

Copy link to clipboard

Copied

I finally got my script to work properly.
Here's to the forum and the few clues you guys gave me.

pathData = pathData.match(/([\d\.]+ ){2}[mlc]\n|\*U\n/ig); //from Illustrator file..
var spAry = [], ppAry = [], sp, pp;
var dirX = -1, dirY = -1, dirXnew, dirYnew, dirCount = 0, prevPoint, cutPoints = [], cutPoint1, cutPoint2;
for(var i = 0, len = pathData.length; i < len; i++){
    if(i % 100 == 0)$.writeln(i);
    if(pathData[i].match(/^\*U\n$/)){ //大文字 U でサブパス区切りとする
        //谷間うめ
        if(cutPoints.length % 2 == 0){
            while(cutPoints.length){
                cutPoint2 = cutPoints.pop();
                cutPoint1 = cutPoints.pop();
                ppAry.splice(cutPoint1, cutPoint2 - cutPoint1);
                }
            }
        sp = new SubPathInfo()
        sp.operation = ShapeOperation.SHAPEADD;
        sp.closed = true;
        sp.entireSubPath = ppAry;
        spAry.push(sp);
        ppAry = [];
        cutPoints = [];
        dirX = -1;
        dirY = -1;
        continue;
        }
    point = pathData[i].match(/[\d\.]+/g);
    if(point){
        pp = new PathPointInfo();
        pp.kind = PointKind.CORNERPOINT;
        pp.anchor = [Math.round(point[0] - 0), Math.round(h - point[1])]; //Y座標は反転
        pp.leftDirection = pp.anchor;
        pp.rightDirection = pp.anchor;
        if(ppAry.length){
            dirXnew = pp.anchor[0] - prevPoint[0];
            dirYnew = pp.anchor[1] - prevPoint[1];
            if(dirXnew == 0) dirXnew = dirX;
            if(dirYnew == 0) dirYnew = dirY;
            dirXnew /= Math.abs(dirXnew);
            dirYnew /= Math.abs(dirYnew);
            if(dirXnew != dirX || dirYnew != dirY){
                dirCount++;
                }
            if(dirXnew != 0) dirX = dirXnew;
            if(dirYnew != 0) dirY = dirYnew;
            if(dirCount >= 3){
                cutPoints.push(ppAry.length - 1);
                dirCount = 0;
                }
            }
        prevPoint = pp.anchor;
        ppAry.push(pp);
       }
    }

//var newpi = doc.pathItems.add("selection", spAry);
add_path("selection", spAry);
var newpi = doc.pathItems.getByName("selection");
newpi.makeSelection(0, false, SelectionType.REPLACE);

 

スクリーンショット 2021-12-02 14.14.06.png

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 02, 2021 Dec 02, 2021

Copy link to clipboard

Copied

It would be nicer to post a script that works 😉

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 02, 2021 Dec 02, 2021

Copy link to clipboard

Copied

Sorry, I can't release the whole code I'm writing now because it's NDA-related.
I'll consider it when I'm less busy.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 04, 2021 Dec 04, 2021

Copy link to clipboard

Copied

What about these areas? 

areaCheck.jpg

Should they not they also qualify as »indentations«? 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 04, 2021 Dec 04, 2021

Copy link to clipboard

Copied

LATEST

I also noticed this problem yesterday.
The area will not be processed.
So I am trying to figure out a way to record the points where the path's Y-coordinate switches direction of travel, and then connect the smallest Y-coordinate point with the second, and likewise the largest point with the second.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 01, 2021 Dec 01, 2021

Copy link to clipboard

Copied

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

 

bbb.png

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 01, 2021 Dec 01, 2021

Copy link to clipboard

Copied

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

I will complete the function of the script soon.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 01, 2021 Dec 01, 2021

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Dec 01, 2021 Dec 01, 2021

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines