Skip to main content
Participating Frequently
October 22, 2023
Question

Script to Generate Line Segments but Needs to Avoid Curved Lines and Multiple Line Segments.

  • October 22, 2023
  • 3 replies
  • 968 views

Hello there!

I've developed a script to create line segments between adjacent selected objects. However, I'm facing two challenges: I want to eliminate curved segments, and I don't want multiple line segments to be generated on a single straight line with multiple anchor points. I've spent hours trying to solve this problem.

Can anyone provide some assistance? Your help is greatly appreciated!



if (app.documents.length > 0) {
  var doc = app.activeDocument;

  var strokeColor = new RGBColor();
  strokeColor.red = 0;
  strokeColor.green = 0;
  strokeColor.blue = 0;
  var strokeWidth = 0.5;

  function areAnchorPointsEqual(point1, point2) {
    return point1.anchor[0] === point2.anchor[0] && point1.anchor[1] === point2.anchor[1];
  }

  var selectedItems = doc.selection;
  for (var i = 0; i < selectedItems.length; i++) {
    var currentItem = selectedItems[i];

    if (currentItem.typename === "GroupItem") {
      // If the selected item is a group, iterate through its pageItems
      for (var k = 0; k < currentItem.pageItems.length; k++) {
        var groupItem = currentItem.pageItems[k];
        processItem(groupItem);
      }
    } else {
      processItem(currentItem);
    }
  }

  function processItem(item) {
    if (item.typename === "PathItem") {
      var pathPoints = item.pathPoints;

      for (var j = 0; j < pathPoints.length; j++) {
        var startPoint = pathPoints[j];
        var endPoint = pathPoints[(j + 1) % pathPoints.length];

        if (!areAnchorPointsEqual(startPoint, endPoint)) {
          var newLine = doc.pathItems.add();
          newLine.setEntirePath([startPoint.anchor, endPoint.anchor]);
          newLine.strokeColor = strokeColor;
          newLine.strokeWidth = strokeWidth;
        }
      }
    } else if (item.typename === "CompoundPathItem") {
      var compoundPathItems = item.pathItems;
      for (var l = 0; l < compoundPathItems.length; l++) {
        var pathItem = compoundPathItems[l];
        var pathPoints = pathItem.pathPoints;

        for (var j = 0; j < pathPoints.length; j++) {
          var startPoint = pathPoints[j];
          var endPoint = pathPoints[(j + 1) % pathPoints.length];

          if (!areAnchorPointsEqual(startPoint, endPoint)) {
            var newLine = doc.pathItems.add();
            newLine.setEntirePath([startPoint.anchor, endPoint.anchor]);
            newLine.strokeColor = strokeColor;
            newLine.strokeWidth = strokeWidth;
          }
        }
      }
    }
  }
}

 
Thanks in Advance!

This topic has been closed for replies.

3 replies

timelyfoxAuthor
Participating Frequently
October 27, 2023

updated code, 

// LINE SEGMENTS//
var doc = app.activeDocument;
//REMOVE THIS AFTER FIXED//

// Set stroke properties for the line segments
function setStrokeProperties(item) {
    item.stroked = true; // Ensure it's stroked
    item.strokeWidth = 2; // Set the stroke width

    var newColor;
    
    // Set the stroke color based on the document's color space
    if (doc.documentColorSpace == DocumentColorSpace.RGB) {
        newColor = new RGBColor();
        newColor.red = 0;
        newColor.green = 0;
        newColor.blue = 0;
    } else if (doc.documentColorSpace == DocumentColorSpace.CMYK) {
        newColor = new CMYKColor();
        newColor.cyan = 0;
        newColor.magenta = 0;
        newColor.yellow = 0;
        newColor.black = 100;
    }

    item.strokeColor = newColor;
}

// Function to set the bezier handle properties
function BEZIER(point, pathPoints, index) {
    // Check if the segment is a curve and avoid generating lines
    if (
        (point.leftDirection[0] !== point.anchor[0] || point.leftDirection[1] !== point.anchor[1]) &&
        (point.rightDirection[0] !== point.anchor[0] || point.rightDirection[1] !== point.anchor[1])
    ) {
        return true;
    }

    // Skip line segment creation of open paths
    if (
        (pathPoints.parent.closed === false) &&
        (index === 0 || index === pathPoints.length - 1)
    ) {
        return true;
    }

    // If none of the above conditions are met, generate lines
    return false;
}

// Function to create line segments with a stable stroke color
function createLineSegment(startPoint, endPoint) {
    var newLine = doc.pathItems.add();
    newLine.setEntirePath([startPoint, endPoint]);
    setStrokeProperties(newLine); // Set stroke properties and color

    // Place the line segment in the "LINE SEGMENTS" layer
    newLine.layer = lineLayer;
}

// Create a new layer for line segments
var lineLayer = doc.layers.add();
lineLayer.name = "LINE SEGMENTS";

// Function to process different item types
function processItem(item) {
    if (item.typename === "GroupItem") {
        var groupItems = item.pageItems;
        for (var j = 0; j < groupItems.length; j++) {
            processItem(groupItems[j]);
        }
    } else if (item.typename === "PathItem") {
        var pathPoints = item.pathPoints;
        if (pathPoints.length === 2) {
            if (
                (pathPoints[0].leftDirection[0] !== pathPoints[0].anchor[0] || pathPoints[0].leftDirection[1] !== pathPoints[0].anchor[1]) &&
                (pathPoints[1].rightDirection[0] !== pathPoints[1].anchor[0] || pathPoints[1].rightDirection[1] !== pathPoints[1].anchor[1])
            ) {
                return; // Skip line segment creation
            }
            createLineSegment(pathPoints[0].anchor, pathPoints[1].anchor);
        } else {
            for (var k = 0; k < pathPoints.length; k++) {
                var startPoint = pathPoints[k];
                var endPoint = pathPoints[(k + 1) % pathPoints.length];
                if (BEZIER(startPoint, pathPoints, k) && BEZIER(endPoint, pathPoints, (k + 1) % pathPoints.length)) {
                    continue; // Skip line segment creation
                }
                createLineSegment(startPoint.anchor, endPoint.anchor);
            }
        }
    } else if (item.typename === "CompoundPathItem") {
        // Recursively process each path item within the compound path
        for (var i = 0; i < item.pathItems.length; i++) {
            processItem(item.pathItems[i]);
        }
    }
}

// Now, process the selected items to generate lines
var selectedItems = doc.selection;
for (var i = 0; i < selectedItems.length; i++) {
  var currentItem = selectedItems[i];

  if (currentItem.layer.name === "DUP") {
      continue;
  }

  processItem(currentItem);
}

 
The last thing I want to remove is in red :

femkeblanco
Brainiac
October 22, 2023

What is the purpose of the script? Can you give the simplest example of what you are using it for? 

timelyfoxAuthor
Participating Frequently
October 23, 2023

Thanks for asking! So, the script's primary purpose is to simplify complex paths by converting straight segments into individual line segments while ignoring curved segments. This can be helpful for various tasks where you want to work with the straight parts of a path, such as simplifying complex shapes or creating basic geometric figures. It is also useful for checking optical characters for small bezier curves within straight lines. By creating line segments from straight path segments and ignoring the curved ones, you can easily identify and isolate areas where the characters or shapes might have unintentional curves. Soon it will be like guiding me in generating grids for straight lines.

timelyfoxAuthor
Participating Frequently
October 22, 2023

Ok, I managed to get it right for the first issue.

if (app.documents.length > 0) {
  var doc = app.activeDocument;

  var strokeColor = new RGBColor();
  strokeColor.red = 0;
  strokeColor.green = 0;
  strokeColor.blue = 0;
  var strokeWidth = 0.5;

  function hasHandles(point) {
    return (
      point.leftDirection[0] !== point.anchor[0] || point.leftDirection[1] !== point.anchor[1] ||
      point.rightDirection[0] !== point.anchor[0] || point.rightDirection[1] !== point.anchor[1]
    );
  }

  var selectedItems = doc.selection;
  for (var i = 0; i < selectedItems.length; i++) {
    var currentItem = selectedItems[i];

    if (currentItem.typename === "GroupItem") {
      // If the selected item is a group, iterate through its pageItems
      for (var k = 0; k < currentItem.pageItems.length; k++) {
        var groupItem = currentItem.pageItems[k];
        processItem(groupItem);
      }
    } else {
      processItem(currentItem);
    }
  }

  function processItem(item) {
    if (item.typename === "PathItem") {
      var pathPoints = item.pathPoints;

      for (var j = 0; j < pathPoints.length; j++) {
        var startPoint = pathPoints[j];
        var endPoint = pathPoints[(j + 1) % pathPoints.length];

        // Check if both anchor points have handles
        if (hasHandles(startPoint) && hasHandles(endPoint)) {
          continue; // Skip line segment creation
        }

        var newLine = doc.pathItems.add();
        newLine.setEntirePath([startPoint.anchor, endPoint.anchor]);
        newLine.strokeColor = strokeColor;
        newLine.strokeWidth = strokeWidth;
      }
    } else if (item.typename === "CompoundPathItem") {
      var compoundPathItems = item.pathItems;
      for (var l = 0; l < compoundPathItems.length; l++) {
        var pathItem = compoundPathItems[l];
        var pathPoints = pathItem.pathPoints;

        for (var j = 0; j < pathPoints.length; j++) {
          var startPoint = pathPoints[j];
          var endPoint = pathPoints[(j + 1) % pathPoints.length];

          // Check if both anchor points have handles
          if (hasHandles(startPoint) && hasHandles(endPoint)) {
            continue; // Skip line segment creation
          }

          var newLine = doc.pathItems.add();
          newLine.setEntirePath([startPoint.anchor, endPoint.anchor]);
          newLine.strokeColor = strokeColor;
          newLine.strokeWidth = strokeWidth;
        }
      }
    }
  }
}

 
one problem to go!

timelyfoxAuthor
Participating Frequently
October 22, 2023

unfortunately, this one still did not get the final result I sought. if a line has an anchor point with outer handles which straightly connected to another anchor point with a handle out. it will refuse to create a line. sigh