10 Replies Latest reply on Aug 28, 2016 3:33 PM by o-marat

    Cutting angled points only

    kylwell

      Odd question but one I've had for a while. In my work there have been times when I needed to convert a shape to a series of lines, keeping the curved parts but breaking the line where it angles. Anybody know of a trick to this other than manually selecting them?

        • 1. Re: Cutting angled points only
          o-marat Level 3

          kylwell, hi!

          This is a function (compatible CS6+) that cuts the shape, which consists only of the corner points (star, poligon, rectangle).

          If I'm on the right way I can add code to handle any paths.

          Before running the script, you need to select the shape.

           

          //@target illustrator
          (function cutCornerShapeByPoints (pth) {
            var i, pnt, nextPnt, pthCut;
            executeMenuCommand ('deselectall');
            for (i = 0; i < pth.pathPoints.length; i++) {
              try {
                pnt     = pth.pathPoints[i];
                nextPnt = pth.pathPoints[i + 1];
              } catch (e) {
                nextPnt = pth.pathPoints[0];
              }
              pnt.selected = PathPointSelection.ANCHORPOINT;
                executeMenuCommand ('copy');
                executeMenuCommand ('pasteFront');
                pthCut = selection[0];
                pthCut.pathPoints[0].remove ();
                executeMenuCommand ('deselectall');
              }  
            pth.remove ();
          } (selection[0]));
          
          • 2. Re: Cutting angled points only
            o-marat Level 3

            Another way - to draw  the new paths (by/using data of) the points of the initial path. Then initial path is removed...

            • 3. Re: Cutting angled points only
              kylwell Level 1

              The only problem with that is I would be redrawing some 100+ paths. The stuff I create can get... complex. While I've done it before I was hoping somebody knew of a script that could help speed the process up. That and it gets really annoying to cut everything and then realize it doesn't work and I need to adjust my offsets.

              • 4. Re: Cutting angled points only
                o-marat Level 3

                kylwell, maybe this script will do.

                /**
                 * ai.jsx (c)MaratShagiev m_js@bk.ru 27.08.2016
                 *
                 * cutPathByCornerPoints_v1.0
                 *
                 * Using:
                 * * Select a single path item;
                 * * Run the script
                 *
                 * Great destination:
                 * * cutting path item into pieces;
                 * * the point of cutting path item - corner points;
                 * * cut closed and open paths;
                 *
                 * What is really going on here:
                 * * source circuit is used as a model;
                 * * on top of the original path created new paths;
                 * * the original path is deleted;
                 */
                //@target illustrator
                cutByCornPnts (selection[0]);
                function cutByCornPnts (pth) {
                  if (_cut (pth)) pth.remove ();
                  function _cut (pth) {
                    var remPth = false;
                    if (pth.closed) {
                      for (var i = 0; i < pth.pathPoints.length; i++) {
                        var pnt = pth.pathPoints[i];
                        if (!__isCornerPoint (pnt)) continue;
                        __addPathByTmpl (pth, i);
                        remPth = true;
                      }
                    } else {
                      for (var i = 0; i < pth.pathPoints.length; i++) {
                        var pnt = pth.pathPoints[i];
                        i       = __addPathByTmpl (pth, i);
                        remPth  = true;
                      }
                    }
                    return remPth;
                    function __addPathByTmpl (pathTmpl, iStartPnt) {
                      var doc       = activeDocument,
                          j, pntTmpl, pthDupl, pnt,
                          endPthAdd = 0,
                          pnts      = [pathTmpl.pathPoints [iStartPnt]];
                      if (pathTmpl.closed) endPthAdd = 1;
                      try {
                        for (j = iStartPnt + 1; j < pathTmpl.pathPoints.length + endPthAdd; j++) {
                          pntTmpl = pathTmpl.pathPoints[j];
                          if (__isCornerPoint (pntTmpl)) {
                            pnts.push (pntTmpl);
                            break;
                          }
                          pntTmpl = pathTmpl.pathPoints[j];
                          pnts.push (pntTmpl);
                        }
                      } catch (e) {
                        for (j = 0; j < iStartPnt + endPthAdd; j++) {
                          pntTmpl = pathTmpl.pathPoints[j];
                          if (__isCornerPoint (pntTmpl)) {
                            pnts.push (pntTmpl);
                            break;
                          }
                          pntTmpl = pathTmpl.pathPoints[j];
                          pnts.push (pntTmpl);
                        }
                      }
                      if (pnts.length > 1) {
                        pthDupl = doc.pathItems.add ();
                        for (var i = 0; i < pnts.length; i++) {
                          var pnt          = pnts[i];
                          var p            = pthDupl.pathPoints.add ();
                          p.anchor         = [pnt.anchor[0], pnt.anchor[1]];
                          p.leftDirection  = [pnt.leftDirection[0], pnt.leftDirection[1]];
                          p.rightDirection = [pnt.rightDirection[0], pnt.rightDirection[1]];
                          p.pointType      = pnt.pointType;
                        }
                      }
                      iStartPnt = j; // for closed paths
                      return --j; // for open paths
                    }
                    /**
                     * Unfortunately the Pen Tool creates all the points as smooth.
                     * Even if in fact they are corner.
                     * One way to solve this problem -
                     * check all the points with this helper.
                     *
                     * @param {Object} pnt - object of class PathPoint
                     * @return {Boolean}
                     * */
                    function __isCornerPoint (pnt) {
                      if (pnt.pointType == PointType.CORNER) return true;
                      var x_1, x_2, x_3,
                          y_1, y_2, y_3,
                          prec    = 100000,
                          precLow = 10;
                      x_1 = Math.round (pnt.leftDirection [0] * prec) / prec; // x
                      y_1 = Math.round (pnt.leftDirection [1] * prec) / prec; // y
                      x_2 = Math.round (pnt.rightDirection [0] * prec) / prec;
                      y_2 = Math.round (pnt.rightDirection [1] * prec) / prec;
                      x_3 = Math.round (pnt.anchor [0] * prec) / prec;
                      y_3 = Math.round (pnt.anchor [1] * prec) / prec;
                      if ((x_1 == x_2 && x_2 == x_3) && (y_1 == y_2 && y_2 == y_3)) return true;
                      if ((x_1 == x_2) && (y_1 == y_2)) return true; // directions is equals
                      if ((x_1 == x_3) && (y_1 == y_3)) return true; // left directon equals with anchor
                      if ((x_2 == x_3) && (y_2 == y_3)) return true; // right direction equals with anchor
                      // The equation of a straight line
                      // points 1, 2, 3 are not equal and don't lie on one straight line
                      if (
                        Math.ceil (((x_3 - x_1) * (y_2 - y_1)) * precLow) / precLow !=
                        Math.ceil (((x_2 - x_1) * (y_3 - y_1)) * precLow) / precLow
                      ) return true;
                      return false;
                    }
                  }
                }
                
                • 5. Re: Cutting angled points only
                  kylwell Level 1

                  I am a complete novice with this, cut & pasted in toa plain text doc, saved as a .jsx and Illustrator refuses to load it. What am I doing wrong?

                  • 6. Re: Cutting angled points only
                    o-marat Level 3

                    On win copy the .jsx file to the Illustrator scripts folder that is in program files or program files (x86).

                    The file path might look like this: C:\Program Files\Adobe\Adobe Illustrator CC 2015\Presets\en_US\scripts\

                    Restart the Illustrator.

                    The script should appear in the menu File>Scripts>...

                     

                    New

                    On Mac OS:

                    Applications >> Adobe Illustrator CC >> Presets >> en_GB >> Scripts

                    “en_GB” is the languages code, so it can be different on your Mac OS.

                    Start or restart Illustrator

                    Go to menu: “File >> Scripts”. The script(s) you just added should appear in the list.

                    • 7. Re: Cutting angled points only
                      kylwell Level 1

                      Why the heck it didn't take it the first 3 times... Ok, it's working and working pretty spiffy. For some odd reason I cannot figure out I have one document that throws up a;

                       

                      Error 8705: Target layer cannot be modified

                      Line: 69

                      -> pthDupl = doc.pathltems.add O;

                       

                      When I try to run it on a path. I can copy & paste the path to another document and it works. Haven't been able to reproduce in on another file but in the meantime, yes it works awesomely. The ONLY improvements I could see would be being able to perform it on multiple paths @ once, and the ability to designate min/max angles.

                       

                      Thanks, this'll save me some seriously tedious work.

                      • 8. Re: Cutting angled points only
                        Silly-V Adobe Community Professional
                        Error 8705: Target layer cannot be modified

                        Make sure that all your layers, especially if it's the top layer are not hidden or locked.

                        • 9. Re: Cutting angled points only
                          kylwell Level 1

                          That was the issue. Once I unlocked and viewed all layers it worked fine. Thanks.

                          • 10. Re: Cutting angled points only
                            o-marat Level 3

                            Now the script works with multiple selected objects (path items and groups), which may be located on different layers. Now you don't need make visible all layers - only select items.

                            About the ability to designate min/max angles: you need the interface (dialog window)? I will try to do it within a week...

                             

                            /**
                             * ai_cs6+.jsx (c)MaratShagiev m_js@bk.ru 29.08.2016
                             *
                             * cutPathByCornerPoints_v2
                             *
                             * What's new:
                             * * Add the process of the collections
                             *
                             * Using:
                             * * Select group[s] or/and path item[s];
                             * * Run the script
                             *
                             * Great destination:
                             * * cutting path item into pieces;
                             * * the point of cutting path item - corner points;
                             * * cut closed and open paths;
                             *
                             * What is really going on here:
                             * * source path is used as a template;
                             * * on top of the original path created new paths;
                             * * the original path is deleted;
                             */
                            //@target illustrator
                            try {
                              var collection = selection;
                              executeMenuCommand ('deselectall');
                              recurs (cutByCornPnts, selection);
                            } catch (e) {
                              alert ('Error: ' + e.message + '\rin line #' + e.line);
                            }
                            function recurs (fn, collection) {
                              if (!collection.length) throw new Error ('Select items and run script');
                              for (var i = 0; i < collection.length; i++) {
                                var elem = collection[i];
                                switch (elem.typename) {
                                  case 'GroupItem':
                                    recurs (fn, elem.pageItems);
                                    break;
                                  case 'PathItem':
                                    fn (elem);
                                    break;
                                  case 'CompoundPathItem':
                                    break;
                                  default:
                                    break;
                                }
                              }
                            }
                            function cutByCornPnts (pth) {
                              pth.selected = true;
                              if (_cut (pth)) pth.remove ();
                              function _cut (pth) {
                                var remPth = false;
                                if (pth.closed) {
                                  for (var i = 0; i < pth.pathPoints.length; i++) {
                                    var pnt = pth.pathPoints[i];
                                    if (!__isCornerPoint (pnt)) continue;
                                    __addPathByTmpl (pth, i);
                                    remPth = true;
                                  }
                                } else {
                                  for (var k = 1; k < pth.pathPoints.length - 1; k++) {
                                    // path that doesn't contain the corner points shouldn't redrawn
                                    if (!__isCornerPoint (pth.pathPoints[k])) continue;
                                    // redraw path that contains corner points
                                    for (var i = 0; i < pth.pathPoints.length; i++) {
                                      var pnt = pth.pathPoints[i];
                                      i       = __addPathByTmpl (pth, i);
                                      remPth  = true;
                                    }
                                    break;
                                  }
                                }
                                pth.selected = false;
                                return remPth;
                                function __addPathByTmpl (pathTmpl, iStartPnt) {
                                  var doc       = activeDocument,
                                      j, pntTmpl, pthDupl, pnt,
                                      endPthAdd = 0,
                                      pnts      = [pathTmpl.pathPoints [iStartPnt]];
                                  if (pathTmpl.closed) endPthAdd = 1;
                                  try {
                                    for (j = iStartPnt + 1; j < pathTmpl.pathPoints.length + endPthAdd; j++) {
                                      pntTmpl = pathTmpl.pathPoints[j];
                                      if (__isCornerPoint (pntTmpl)) {
                                        pnts.push (pntTmpl);
                                        break;
                                      }
                                      pntTmpl = pathTmpl.pathPoints[j];
                                      pnts.push (pntTmpl);
                                    }
                                  } catch (e) {
                                    for (j = 0; j < iStartPnt + endPthAdd; j++) {
                                      pntTmpl = pathTmpl.pathPoints[j];
                                      if (__isCornerPoint (pntTmpl)) {
                                        pnts.push (pntTmpl);
                                        break;
                                      }
                                      pntTmpl = pathTmpl.pathPoints[j];
                                      pnts.push (pntTmpl);
                                    }
                                  }
                                  if (pnts.length > 1) {
                                    pthDupl = doc.activeLayer.pathItems.add ();
                                    pthDupl.move (pathTmpl, ElementPlacement.PLACEBEFORE);
                                    for (var i = 0; i < pnts.length; i++) {
                                      var pnt          = pnts[i];
                                      var p            = pthDupl.pathPoints.add ();
                                      p.anchor         = [pnt.anchor[0], pnt.anchor[1]];
                                      p.leftDirection  = [pnt.leftDirection[0], pnt.leftDirection[1]];
                                      p.rightDirection = [pnt.rightDirection[0], pnt.rightDirection[1]];
                                      p.pointType      = pnt.pointType;
                                    }
                                  }
                                  iStartPnt = j; // for closed paths
                                  return --j; // for open paths
                                }
                                /**
                                 * Unfortunately the Pen Tool creates all the points as smooth.
                                 * Even if in fact they are corner.
                                 * One way to solve this problem -
                                 * check all the points with this helper.
                                 *
                                 * todo: make this function more accurate...
                                 *
                                 * @param {Object} pnt - object of class PathPoint
                                 * @return {Boolean}
                                 * */
                                function __isCornerPoint (pnt) {
                                  if (pnt.pointType == PointType.CORNER) return true;
                                  var x_1, x_2, x_3,
                                      y_1, y_2, y_3,
                                      prec    = 100000,
                                      precLow = 10;
                                  x_1 = Math.round (pnt.leftDirection [0] * prec) / prec; // x
                                  y_1 = Math.round (pnt.leftDirection [1] * prec) / prec; // y
                                  x_2 = Math.round (pnt.rightDirection [0] * prec) / prec;
                                  y_2 = Math.round (pnt.rightDirection [1] * prec) / prec;
                                  x_3 = Math.round (pnt.anchor [0] * prec) / prec;
                                  y_3 = Math.round (pnt.anchor [1] * prec) / prec;
                                  if ((x_1 == x_2 && x_2 == x_3) && (y_1 == y_2 && y_2 == y_3)) return true;
                                  if ((x_1 == x_2) && (y_1 == y_2)) return true; // directions is equals
                                  if ((x_1 == x_3) && (y_1 == y_3)) return true; // left directon equals with anchor
                                  if ((x_2 == x_3) && (y_2 == y_3)) return true; // right direction equals with anchor
                                  // The equation of a straight line
                                  // points 1, 2, 3 are not equal and don't lie on one straight line
                                  if (
                                    Math.ceil (((x_3 - x_1) * (y_2 - y_1)) * precLow) / precLow !=
                                    Math.ceil (((x_2 - x_1) * (y_3 - y_1)) * precLow) / precLow
                                  ) return true;
                                  return false;
                                }
                              }
                            }