Copy link to clipboard
Copied
hello,everyone.
i want to change the strokeCap of all objects in a particular layer.
var document = app.activeDocument;
var allLayers = app.activeDocument.layers;
var testLayer = ["a", "b"];
function lineFormat(LayerName) {
//Select objects in layer
document.activeLayer = document.layers[LayerName];
//document.activeLayer.hasSelectedArtwork = true;
//Change Style
document.activeLayer.pathItems.stroked = true; // open stroke
document.activeLayer.pathItems.strokeCap = StrokeCap.BUTTENDCAP;//ROUNDENDCAP, PROJECTINGENDCAP
document.activeLayer.pathItems.strokeJoin = StrokeJoin.ROUNDENDJOIN;//BEVELENDJOIN, MITERENDJOIN
//Deselect objects in layer
//document.activeLayer.hasSelectedArtwork = false;
}
for (var i = 0, il = allLayers.length; i < il; i++) {
var curLayer = allLayers[i]
if (curLayer = testLayer[i]) {
//if layer name found
lineFormat(testLayer[i])
}
}
then,i wrote the code as I understood it, but nothing happened to it for now, I don't know how to fix this code
Anyone can help me?
Sorry, had a typo and a faulty condition. Serves me right for so confidently offering recursion thinking I had cracked it so easily ha, I've verified the below on your file:
var targetLayers = ["Test"];
function getAllPathItems(parent) {
var list = [];
for (var i = 0; i < parent.pageItems.length; i++) {
var item = parent.pageItems[i];
if (item.pageItems && item.pageItems.length)
list = [].concat(list, getAllPathItems(item));
else if (/path/i.test(item.typename) && !/compou
...
Copy link to clipboard
Copied
Hello, consider this:
var document = app.activeDocument;
var allLayers = app.activeDocument.layers;
var testLayers = ["Test"];
// Why do this? Because if we query a layer name that doesn't exist, it causes silent failure.
function getLayer(layerName) {
try {
return document.layers.getByName(layerName);
} catch(err) {
return null;
}
}
function restyleAllPathItemsWithin(layers) {
// An alternative to deselect all artwork, though it shouldn't actually matter here
// because we can change the strokes regardless of whether other art is selected
app.selection = null;
// Iterate through our layer list:
for (var i = 0; i < layers.length; i++) {
// Get our target layer:
var layer = getLayer(layers[i]);
// If a layer wasn't found or there are no items to restyle, continue looping:
if (!layer || !layer.pathItems.length) continue;
else {
// Layer.pathItems is a collection of objects, not a single one.
// To restyle any given object, we have to iterate over them individually:
for (var index = 0; index < layer.pathItems.length; index++) {
var pathItem = layer.pathItems[index];
pathItem.stroked = true; // open stroke
pathItem.strokeCap = StrokeCap.BUTTENDCAP;//ROUNDENDCAP, PROJECTINGENDCAP
pathItem.strokeJoin = StrokeJoin.ROUNDENDJOIN;//BEVELENDJOIN, MITERENDJOIN
}
}
}
}
restyleAllPathItemsWithin(testLayers);
Essentially you have everything correct here, but the issue is that you're trying to assign properties to an Array-like collection (pathItems) rather than one entry of that collection (i.e., pathItems[0]).
Copy link to clipboard
Copied
thanks you for you help!!!but it seems that the straight lines I import from DWG still need to be ungrouped before they work.
Copy link to clipboard
Copied
No worries. That's true, it has to do with how AI contains items. For instance:
Layer.pathItems is not every path inside of the layer, only every path whose parent is the layer. The issue would be that a group counts as a pageItem, so a path inside of a group would be something more like:
Layer.pathItems only contains paths that aren't in a group or a compound path, if the parent is explicitly the layer. We can fix this for shallow groups pretty easily:
function getAllPathItemsInLayer(layer) {
var list = [];
for (var i = 0; i < layer.pageItems.length; i++) {
var item = layer.pageItems[i];
// If this is a group or compound path, we need to add it's pathItems to our list:
if (
/group|compound/i.test(item.typename) &&
item.pathItems &&
item.pathItems.length
) {
for (var e = 0; e < item.pathItems.length; e++)
list.push(item.pathItems[e]);
} else if (/path/i.test(item.typename)) {
// Otherwise if this is a pathItem, we can add it to the list directly:
list.push(item);
}
}
return list;
}
function getLayer(layerName) {
try {
return document.layers.getByName(layerName);
} catch (err) {
return null;
}
}
function restyleAllPathItemsWithin(layers) {
app.selection = null;
for (var i = 0; i < layers.length; i++) {
var layer = getLayer(layers[i]);
if (!layer || !layer.pathItems.length) continue;
else {
// We need to gather any children pathItems in case their parent is a Group/Compound Path
var list = getAllPathItemsInLayer(layer);
for (var index = 0; index < list.length; index++) {
var pathItem = list[index];
pathItem.stroked = true; // open stroke
pathItem.strokeCap = StrokeCap.BUTTENDCAP; //ROUNDENDCAP, PROJECTINGENDCAP
pathItem.strokeJoin = StrokeJoin.ROUNDENDJOIN; //BEVELENDJOIN, MITERENDJOIN
}
}
}
}
restyleAllPathItemsWithin(testLayers);
But for complicated groups (pathItems within groups within groups or any dynamic nesting) then we'd have to do some recursion and it's likely going to look either very intimidating and confusing or very simple and confusing.
Copy link to clipboard
Copied
i see what you mean, but it still does not happen to work,i uploaded the test file for you.
and Thanks tyour help, I'm afraid it would be difficult for me to write such code (although I can understand it)
Copy link to clipboard
Copied
Sorry, I don't see the file yet. If you happened to try running the above snippet directly though, you'd be missing the value of "testLayers" as the param in case that was the issue.
Copy link to clipboard
Copied
Sorry, I can't seem to send the file. But I have added "testLayers"
Copy link to clipboard
Copied
Here's recursion in case you have deep nesting:
var targetLayers = ["Test"];
function getAllPathItems(parent) {
var list = [];
for (var i = 0; i < parent.pageItems.length; i++) {
var item = parent.pageItems[i];
if (item.pageItems && item.pageItems.length)
// We call this same function to rerun within it's own loop:
list = [].concat(list, getAllPathItems(item));
else if (/path/i.test(item.typename) && !/compound/i.test(item.typename))
list.push(item);
}
return list;
}
function getLayer(layerName) {
try {
return document.layers.getByName(layerName);
} catch (err) {
return null;
}
}
function restyleAllPathItemsWithin(layers) {
app.selection = null;
for (var i = 0; i < layers.length; i++) {
var layer = getLayer(layers[i]);
if (!layer || !layer.pathItems.length) continue;
else {
var list = getAllPathItems(layer);
for (var index = 0; index < list.length; index++) {
var pathItem = list[index];
pathItem.stroked = true; // open stroke
pathItem.strokeCap = StrokeCap.BUTTENDCAP; //ROUNDENDCAP, PROJECTINGENDCAP
pathItem.strokeJoin = StrokeJoin.ROUNDENDJOIN; //BEVELENDJOIN, MITERENDJOIN
}
}
}
}
restyleAllPathItemsWithin(targetLayers);
Copy link to clipboard
Copied
Sorry, the bad news is that it still doesn't work. I opened the dwg with AI and ran the code directly (the target layer was already there) and nothing happened.
But if I undo one of the groups, the code starts working again.
Copy link to clipboard
Copied
🤔 Hmmm, I thought that'd work. It's pretty hard to do this blindly, can you upload the file and link here?
Copy link to clipboard
Copied
Here is the test file
Copy link to clipboard
Copied
Sorry, had a typo and a faulty condition. Serves me right for so confidently offering recursion thinking I had cracked it so easily ha, I've verified the below on your file:
var targetLayers = ["Test"];
function getAllPathItems(parent) {
var list = [];
for (var i = 0; i < parent.pageItems.length; i++) {
var item = parent.pageItems[i];
if (item.pageItems && item.pageItems.length)
list = [].concat(list, getAllPathItems(item));
else if (/path/i.test(item.typename) && !/compound/i.test(item.typename))
list.push(item);
}
return list;
}
function getLayer(layerName) {
try {
return app.activeDocument.layers.getByName(layerName);
} catch (err) {
return null;
}
}
function restyleAllPathItemsWithin(layers) {
app.selection = null;
for (var i = 0; i < layers.length; i++) {
var layer = getLayer(layers[i]);
if (!layer) continue;
else {
var list = getAllPathItems(layer);
for (var index = 0; index < list.length; index++) {
var pathItem = list[index];
pathItem.stroked = true; // open stroke
pathItem.strokeCap = StrokeCap.BUTTENDCAP; //ROUNDENDCAP, PROJECTINGENDCAP
pathItem.strokeJoin = StrokeJoin.ROUNDENDJOIN; //BEVELENDJOIN, MITERENDJOIN
}
}
}
}
restyleAllPathItemsWithin(targetLayers);
I'm not sure if you're wanting to target only specific layers by name or if you're just trying to change all document strokes -- you could do that though. If the goal is to change all strokes we could just feed a list of all the layers into the main function, and it might be easier to choose which layers (or names of annotation like "LWPOLYLINE") to exclude rather than include. Or target all "LINE" group children, etc.
Copy link to clipboard
Copied
that cool !!!and you are right, we can narrow down the scope of the code to work