• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Convert Live Shape to regular path via Javascript

Advocate ,
Oct 12, 2017 Oct 12, 2017

Copy link to clipboard

Copied

I have a script which needs to merge paths made up of multiple subpaths into a single path, and sometimes I get the dialog 'This operation will turn a live shape into a regular path'.

Is there a command to convert the paths/subpaths which are live shapes into a regular path (and also to determine which are live shape paths that need to be converted) via Javascript?

TOPICS
Actions and scripting

Views

2.1K

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

correct answers 1 Correct answer

Valorous Hero , Nov 20, 2017 Nov 20, 2017

A small note )

You can use the dup_to_wrk_path () function instead of the combination
"collectPathInfoFromDesc2012" and "createPath2015". It works instantly, while the proposed functions can suspend photoshop with the number of points in many thousands.

function dup_to_wrk_path(id)

    {

    try

        {

        var d = new ActionDescriptor();

        var r = new ActionReference();

        if (id == undefined)             r.putEnumerated(stringIDToTypeID("path"), charIDToTypeID("Ordn"), charIDToTypeID("

...

Votes

Translate

Translate
Community Expert ,
Oct 14, 2017 Oct 14, 2017

Copy link to clipboard

Copied

Could you please post a screenshot to illustrate the Layer structure (as its is and the result you want to achieve)?

Votes

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
Advocate ,
Nov 01, 2017 Nov 01, 2017

Copy link to clipboard

Copied

Sorry I haven't been able to reply until now.

What I'm doing is merging shape components, the equivalent of this menu in the path dropdown in the interface:

MergingPathComponents.jpg

This works, but sometimes there's a live shape in the paths, and this dialog appears:

Alert.jpg

I'm looking for a solution to allow my script to merge the paths if there is a live shape included.

Votes

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 Expert ,
Nov 01, 2017 Nov 01, 2017

Copy link to clipboard

Copied

Your script should still merge the paths. Is it not doing that, when you click the OK button? I would also check the "Do not show again" so that doesn't appear.

Votes

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
Advocate ,
Nov 01, 2017 Nov 01, 2017

Copy link to clipboard

Copied

I would like it to do the merge without providing the dialog. This is meant to run somewhat unattended, and I cannot control whether the user will have that option checked or not

Votes

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 Expert ,
Nov 19, 2017 Nov 19, 2017

Copy link to clipboard

Copied

A possible workaround:

Collect the subPathInfo and create a new Path based on that, remove the Vector Mask, select the newly created Path, add a Vector Mask and remove the intermediate Path.

Edit:

#target photoshop

var myDocument = activeDocument;

var theArray = collectPathInfoFromDesc2012 (myDocument, selectedPath2015 ());

var thePathName = Math.random();

var thePath = createPath2015(theArray, thePathName);

// =======================================================

var idDlt = charIDToTypeID( "Dlt " );

    var desc9 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref2 = new ActionReference();

        var idPath = charIDToTypeID( "Path" );

        var idPath = charIDToTypeID( "Path" );

        var idvectorMask = stringIDToTypeID( "vectorMask" );

        ref2.putEnumerated( idPath, idPath, idvectorMask );

        var idLyr = charIDToTypeID( "Lyr " );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref2.putEnumerated( idLyr, idOrdn, idTrgt );

    desc9.putReference( idnull, ref2 );

executeAction( idDlt, desc9, DialogModes.NO );

myDocument.pathItems[thePathName].select();

// =======================================================

var idMk = charIDToTypeID( "Mk  " );

    var desc11 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref4 = new ActionReference();

        var idPath = charIDToTypeID( "Path" );

        ref4.putClass( idPath );

    desc11.putReference( idnull, ref4 );

    var idAt = charIDToTypeID( "At  " );

        var ref5 = new ActionReference();

        var idPath = charIDToTypeID( "Path" );

        var idPath = charIDToTypeID( "Path" );

        var idvectorMask = stringIDToTypeID( "vectorMask" );

        ref5.putEnumerated( idPath, idPath, idvectorMask );

    desc11.putReference( idAt, ref5 );

    var idUsng = charIDToTypeID( "Usng" );

        var ref6 = new ActionReference();

        var idPath = charIDToTypeID( "Path" );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref6.putEnumerated( idPath, idOrdn, idTrgt );

    desc11.putReference( idUsng, ref6 );

executeAction( idMk, desc11, DialogModes.NO );

// =======================================================

var idcombine = stringIDToTypeID( "combine" );

    var desc4 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref1 = new ActionReference();

        var idPath = charIDToTypeID( "Path" );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref1.putEnumerated( idPath, idOrdn, idTrgt );

    desc4.putReference( idnull, ref1 );

executeAction( idcombine, desc4, DialogModes.NO );

myDocument.pathItems[thePathName].remove();

////// collect path info from actiondescriptor, smooth added //////

function collectPathInfoFromDesc2012 (myDocument, thePath) {

var originalRulerUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.POINTS;

//app.preferences.rulerUnits = Units.PIXELS;

// based of functions from xbytor’s stdlib;

var ref = new ActionReference();

for (var l = 0; l < myDocument.pathItems.length; l++) {

  var thisPath = myDocument.pathItems;

  if (thisPath == thePath && thisPath.kind == PathKind.WORKPATH) {

  ref.putProperty(cTID("Path"), cTID("WrPt"));

  };

  if (thisPath == thePath && thisPath.kind != PathKind.WORKPATH && thisPath.kind != PathKind.VECTORMASK) {

  ref.putIndex(cTID("Path"), l + 1);

  };

  if (thisPath == thePath && thisPath.kind == PathKind.VECTORMASK) {

        var idPath = charIDToTypeID( "Path" );

        var idPath = charIDToTypeID( "Path" );

        var idvectorMask = stringIDToTypeID( "vectorMask" );

        ref.putEnumerated( idPath, idPath, idvectorMask );

  };

  };

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 || cTID = app.charIDToTypeID(s); };

function sTID (s) { return sTID || sTID = app.stringIDToTypeID(s); };

// reset;

app.preferences.rulerUnits = originalRulerUnits;

return theArray;

};

////// create a path from collectPathInfoFromDesc2012-array //////

function createPath2015(theArray, thePathsName) {

var originalRulerUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.PIXELS;

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

    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;

    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 check = false;

var x = activeDocument.pathItems.length - 1;

while (check == false) {

if (activeDocument.pathItems.kind == PathKind.WORKPATH) {

app.activeDocument.pathItems.name = thePathsName;

var myPathItem = app.activeDocument.pathItems;

check = true

};

x--

};

app.preferences.rulerUnits = originalRulerUnits;

return myPathItem

};

////// determine selected path, updated 09.2015 //////

function selectedPath2015 () {

try {

var ref = new ActionReference();

ref.putProperty (stringIDToTypeID("property"), stringIDToTypeID("targetPathIndex"));

ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

var docDesc = executeActionGet(ref);

return app.activeDocument.pathItems[docDesc.getInteger(stringIDToTypeID("targetPathIndex"))]

}

catch (e) {return undefined}

};

Votes

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 Expert ,
Nov 19, 2017 Nov 19, 2017

Copy link to clipboard

Copied

I forgot to mention one should include a check to verify whether the Vector Mask has Feather and Density settings …

Votes

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
Valorous Hero ,
Nov 20, 2017 Nov 20, 2017

Copy link to clipboard

Copied

A small note )

You can use the dup_to_wrk_path () function instead of the combination
"collectPathInfoFromDesc2012" and "createPath2015". It works instantly, while the proposed functions can suspend photoshop with the number of points in many thousands.

function dup_to_wrk_path(id)

    {

    try

        {

        var d = new ActionDescriptor();

        var r = new ActionReference();

        if (id == undefined)             r.putEnumerated(stringIDToTypeID("path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

        else if (typeof(id) == "string") r.putName( charIDToTypeID( "Path" ), id);

        else                             r.putIdentifier( charIDToTypeID( "Path" ), id);

        var path = executeActionGet(r).getObjectValue(stringIDToTypeID("pathContents"));          

        var list = path.getList(stringIDToTypeID("pathComponents"));          

        var r = new ActionReference();

        r.putProperty( charIDToTypeID( "Path" ), charIDToTypeID( "WrPt" ) );

        d.putReference( stringIDToTypeID( "null" ), r );

        d.putList(charIDToTypeID("T   "), list);

        executeAction(charIDToTypeID("setd"), d, DialogModes.NO);

        return true;

        }

    catch (e) { alert(e); return false; }

    }

Votes

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
Participant ,
Apr 27, 2023 Apr 27, 2023

Copy link to clipboard

Copied

Do you by any chance have a full script? The one OP posted below is erroring out. I'm trying to cobble together a function that converts a live path to a regular path. I'm not sure how to use your dup_to_wrk_path function. What do I pass as the ID? Any chance you could help me out?

Would really appreciate it!

Votes

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
Valorous Hero ,
Apr 27, 2023 Apr 27, 2023

Copy link to clipboard

Copied

LATEST

There were errors when transferring a topic from the old forum.

ccc.jpg

 

You can use nothing as an ID, i.e. empty: dup_to_wrk_path();

In this case, the current selected path will be duplicated.

You can also use the path name: dup_to_wrk_path("Path 1");

 

Votes

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
Advocate ,
Nov 22, 2017 Nov 22, 2017

Copy link to clipboard

Copied

Thank you both for the examples, I'll look into this further when my workload allows it.

Recreating the path sounds promising, but might be a bit problematic if it has to do that every time the program comes across a path. Depending on how complicated the paths might be, it could cause a very undesired slowdown. And since I don't see any way to determine if the path is/contains a 'live path', I would have to recreate every path.

These are actually clipping paths, not vector masks, so I shouldn't have to worry about any settings other than duplicating the path and applying the existing clipping path properties.


Thanks again.

Votes

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
Advocate ,
Nov 22, 2017 Nov 22, 2017

Copy link to clipboard

Copied

Success!

I used r-bin's solution, and modified it to my needs, attached is the code that I will be using:

var myDocument = activeDocument;

var theClippingPath = getClippingPath (myDocument)

if (theClippingPath != null) {

    var pathName = theClippingPath.name

    dup_to_wrk_path(pathName ) 

    var thePath = getWorkPath (myDocument)

    if (thePath != null) {

        theClippingPath.remove()

        thePath.name = pathName //'Clipping Path'

        thePath.makeClippingPath()

    } else {

        alert ('Work path not found?')

    }

}

function getClippingPath (oDoc) {

    var ct = oDoc.pathItems.length;

    if (ct > 0) {

        for( var i = 0; i< ct; i++) {

            var p = oDoc.pathItems;

            if (p.kind == PathKind.CLIPPINGPATH) {

                return p

            }

        }

    } 

    return null

}

function getWorkPath (oDoc) {

    var ct = oDoc.pathItems.length;

    if (ct > 0) {

        for( var i = 0; i< ct; i++) {

            var p = oDoc.pathItems;

            if (p.kind == PathKind.WORKPATH) {

                return p

            }

        }

    } 

    return null

}

function dup_to_wrk_path(id) { 

    try 

        { 

        var d = new ActionDescriptor(); 

        var r = new ActionReference(); 

 

        if (id == undefined)             r.putEnumerated(stringIDToTypeID("path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 

        else if (typeof(id) == "string") r.putName( charIDToTypeID( "Path" ), id); 

        else                             r.putIdentifier( charIDToTypeID( "Path" ), id); 

 

        var path = executeActionGet(r).getObjectValue(stringIDToTypeID("pathContents"));            

 

        var list = path.getList(stringIDToTypeID("pathComponents"));            

 

        var r = new ActionReference(); 

        r.putProperty( charIDToTypeID( "Path" ), charIDToTypeID( "WrPt" ) ); 

 

        d.putReference( stringIDToTypeID( "null" ), r ); 

        d.putList(charIDToTypeID("T   "), list); 

 

        executeAction(charIDToTypeID("setd"), d, DialogModes.NO); 

 

        return true; 

        }  catch (e) {

            alert(e); return false;

        } 

  } 

Votes

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