Welcome Dialog

Welcome to the Community!

We have a brand new look! Take a tour with us and explore the latest updates on Adobe Support Community.


Kit numbering in order

New Here ,
Nov 09, 2021 Nov 09, 2021

Copy link to clipboard

Copied

Hi,

 

Really hoping someone out there can help. Currently I number these kits manually with hundreds to contend with and I am desperately seeking an easier way. I have found a script that is like a colouring book effect which works a little. I really need to number from bottom to top / left to right. I have tried to show some sort of example below.

 

The link below is for a pdf with the sort of work I need numbering.

Adobe Document Cloud

defaultb28wt91xe06u_0-1636452531289.jpeg

 

I really appreciate every bit of help I get with this. I may even be able to get a pay rise with this!!! If I do I will send a reward!!!

 

Thanks

RKG

TOPICS
How to, Scripting

Views

151

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

correct answers 1 Correct answer

Enthusiast , Nov 09, 2021 Nov 09, 2021
I think numbering those paths might be a tricky problem. The question is how do you sort them so that the numbers can be automatically entered. If you sort, naively, by x and y, it isn't right because, for example, the left and top of your part labelled 1 is to the right and below the left and top of part labelled 2.Here's a quick hack of your code that illustrates this issue: (function () { var doc = app.activeDocument, lays = doc.layers, WORK_LAY = lays.add(), NUM_L...

Likes

Translate

Translate
Adobe Community Professional ,
Nov 09, 2021 Nov 09, 2021

Copy link to clipboard

Copied

It would probably be helpful to any scripters reading if you linked to the original topic:

https://community.adobe.com/t5/illustrator-discussions/script-insert-text-number-in-the-middle-of-vi...

 

You're still chasing that pay rise three years on?

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
New Here ,
Nov 09, 2021 Nov 09, 2021

Copy link to clipboard

Copied

Yes still chasing lol, my review is coming up this week!. 

 

Thanks for the quick response. I have this script, I just need to change the font and have the numbers go up in value as they all come out as 1. Is this possible!?

 

defaultb28wt91xe06u_0-1636458936617.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 ,
Nov 09, 2021 Nov 09, 2021

Copy link to clipboard

Copied

I'm afraid I'm not a scripter, I just thought it would be helpful to anyone reading to have the full history of the project. I hope someone can help you out.

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 09, 2021 Nov 09, 2021

Copy link to clipboard

Copied

Hi,

I have written same kind of script earlier. You can share your script so that we can look and help you out. Without looking at the script it won't be possible to guide you in right direction.

Best 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
New Here ,
Nov 09, 2021 Nov 09, 2021

Copy link to clipboard

Copied

Visual Centre

 

(function() {
var doc = app.activeDocument,
lays = doc.layers,
WORK_LAY = lays.add(),
NUM_LAY = lays.add(),
i = lays.length - 1,
lay;

// main working loop
for (; i > 1; i--) {
//process each layer
lay = lays[i];
lay.name = lay.name + " Num:" + (i - 1); // i-1 as 2 layers beed added.
process(lay.pathItems, false);
process(lay.compoundPathItems, true); // if any
}
//clean up
NUM_LAY.name = "Numbers";
WORK_LAY.remove();

function process(items, isCompound) {
var j = 0,
b, xy, s, p, op;

for (; j < items.length; j++) {
// process each pathItem
op = items[j];
// add stroke
if (isCompound) {
strokeComPath(op);
} else {
!op.closed && op.closed = true;
op.filled = false;
op.stroked = true;
};
b = getCenterBounds(op);
xy = [b[0] + (b[2] - b[0]) / 2, b[1] + (b[3] - b[1]) / 2];
s = (
Math.min(op.height, op.width) < 20 ||
(op.area && Math.abs(op.area) < 150)
) ? 4 : 6; // adjust font size for small area paths.
add_nums(i - 1, xy, s);
}
}

function getMinVisibleSize(b) {
var s = Math.min(b[2] - b[0], b[1] - b[3]);
return Math.abs(s);
}

function getGeometricCenter(p) {
var b = p.geometricBounds;
return [(b[0] + b[2]) / 2, (b[1] + b[3]) / 2];
}

// returns square of distance between p1 and p2
function getDist2(p1, p2) {
return Math.pow(p1[0] + p2[0], 2) + Math.pow(p1[1] + p2[1], 2);
}

// returns visibleBounds of a path in a compoundPath p
// which is closest to center of the original path op
function findBestBounds(op, p) {
var opc = getGeometricCenter(op);
var idx = 0,
d;
var minD = getDist2(opc, getGeometricCenter(p.pathItems[0]));
for (var i = 0, iEnd = p.pathItems.length; i < iEnd; i++) {
d = getDist2(opc, getGeometricCenter(p.pathItems[i]));
if (d < minD) {
minD = d;
idx = i;
}
}
return p.pathItems[idx].visibleBounds;
}

function applyOffset(op, checkBounds) {
var p = op.duplicate(WORK_LAY, ElementPlacement.PLACEATBEGINNING),
// offset value the small the better, but meantime more slow.
offset = function() {
var minsize = Math.min(p.width, p.height);
if (minsize >= 50) {
return '-1'
} else if (20 < minsize && minsize < 50) {
return '-0.5'
} else {
return '-0.2' // 0.2 * 2 (both side ) * 50 (Times) = 20
}
},
xmlstring = '<LiveEffect name="Adobe Offset Path"><Dict data="I jntp 2 R mlim 4 R ofst #offset"/></LiveEffect>'
.replace('#offset', offset()),
TIMES = 100; // if shapes are too large, should increase the value.

if (checkBounds) {
// check its size only if it needs, because it's too slow
while (TIMES-- && getMinVisibleSize(p.visibleBounds) > 3) p.applyEffect(xmlstring);
} else {
while (TIMES--) p.applyEffect(xmlstring);
}
return p;
}

function getCenterBounds(op) {
var originalMinSize = getMinVisibleSize(op.visibleBounds);

var p = applyOffset(op, false);

if (getMinVisibleSize(p.visibleBounds) > originalMinSize) {
// in some cases, path p becomes larger for some unknown reason
p.remove();
p = applyOffset(op, true);
}

var b = p.visibleBounds;

if (getMinVisibleSize(b) > 10) {
activeDocument.selection = [p];
executeMenuCommand("expandStyle");
p = activeDocument.selection[0];
if (p.typename == "CompoundPathItem") {
b = findBestBounds(op, p);
}
}

p.remove();
return b;
}

function add_nums(n, xy, s) {
var txt = NUM_LAY.textFrames.add();

txt.contents = n;
txt.textRange.justification = Justification.CENTER;
txt.textRange.characterAttributes.size = s;
txt.position = [xy[0] - txt.width / 2, xy[1] + txt.height / 2];
}

function strokeComPath(compoundPath) {
var p = compoundPath.pathItems,
l = p.length,
i = 0;

for (; i < l; i++) {
!p[i].closed && p[i].closed = true;
p[i].stroked = true;
p[i].filled = false;
};
}

})();

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 09, 2021 Nov 09, 2021

Copy link to clipboard

Copied

Hi,

What I understand is tht you need to number your items from 1 to n.. Is that corret?

Or it will be numbered based on the colors? For an example: All reds are 1, all yellows are 2.. and so on.

 

 

Best 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
New Here ,
Nov 09, 2021 Nov 09, 2021

Copy link to clipboard

Copied

Numbered 1 to n is correct.

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
Enthusiast ,
Nov 09, 2021 Nov 09, 2021

Copy link to clipboard

Copied

I think numbering those paths might be a tricky problem. The question is how do you sort them so that the numbers can be automatically entered. If you sort, naively, by x and y, it isn't right because, for example, the left and top of your part labelled 1 is to the right and below the left and top of part labelled 2.

Here's a quick hack of your code that illustrates this issue:

Screen Shot 2021-11-10 at 9.04.19 am.png

 

(function () {
    var doc = app.activeDocument,
        lays = doc.layers,
        WORK_LAY = lays.add(),
        NUM_LAY = lays.add(),
        i = lays.length - 1,
        lay,
        allNumLabels = [];
    // main working loop
    for (; i > 1; i--) {
        //process each layer
        lay = lays[i];
        lay.name = lay.name + " Num:" + (i - 1); // i-1 as 2 layers beed added.
        process(lay.pathItems, false);
        process(lay.compoundPathItems, true); // if any
    }
    //number the labels
    allNumLabels.sort(function (a, b) { return (b.top - a.top || a.left - b.left) })
    for (var i = 0; i < allNumLabels.length; i++) {
        allNumLabels[i].contents = i+1;
    }
    //clean up
    NUM_LAY.name = "Numbers";
    WORK_LAY.remove();
    function process(items, isCompound) {
        var j = 0,
            b, xy, s, p, op;
        for (; j < items.length; j++) {
            // process each pathItem
            op = items[j];
            // add stroke
            if (isCompound) {
                strokeComPath(op);
            } else {
                op.closed = true;
                op.filled = false;
                op.stroked = true;
            };
            b = getCenterBounds(op);
            xy = [b[0] + (b[2] - b[0]) / 2, b[1] + (b[3] - b[1]) / 2];
            s = (
                Math.min(op.height, op.width) < 20 ||
                (op.area && Math.abs(op.area) < 150)
            ) ? 4 : 6; // adjust font size for small area paths.
            add_nums(xy, s);
        }
    }
    function getMinVisibleSize(b) {
        var s = Math.min(b[2] - b[0], b[1] - b[3]);
        return Math.abs(s);
    }
    function getGeometricCenter(p) {
        var b = p.geometricBounds;
        return [(b[0] + b[2]) / 2, (b[1] + b[3]) / 2];
    }
    // returns square of distance between p1 and p2
    function getDist2(p1, p2) {
        return Math.pow(p1[0] + p2[0], 2) + Math.pow(p1[1] + p2[1], 2);
    }
    // returns visibleBounds of a path in a compoundPath p
    // which is closest to center of the original path op
    function findBestBounds(op, p) {
        var opc = getGeometricCenter(op);
        var idx = 0,
            d;
        var minD = getDist2(opc, getGeometricCenter(p.pathItems[0]));
        for (var i = 0, iEnd = p.pathItems.length; i < iEnd; i++) {
            d = getDist2(opc, getGeometricCenter(p.pathItems[i]));
            if (d < minD) {
                minD = d;
                idx = i;
            }
        }
        return p.pathItems[idx].visibleBounds;
    }
    function applyOffset(op, checkBounds) {
        var p = op.duplicate(WORK_LAY, ElementPlacement.PLACEATBEGINNING),
            // offset value the small the better, but meantime more slow.
            offset = function () {
                var minsize = Math.min(p.width, p.height);
                if (minsize >= 50) {
                    return '-1'
                } else if (20 < minsize && minsize < 50) {
                    return '-0.5'
                } else {
                    return '-0.2' // 0.2 * 2 (both side ) * 50 (Times) = 20
                }
            },
            xmlstring = '<LiveEffect name="Adobe Offset Path"><Dict data="I jntp 2 R mlim 4 R ofst #offset"/></LiveEffect>'
                .replace('#offset', offset()),
            TIMES = 100; // if shapes are too large, should increase the value.
        if (checkBounds) {
            // check its size only if it needs, because it's too slow
            while (TIMES-- && getMinVisibleSize(p.visibleBounds) > 3) p.applyEffect(xmlstring);
        } else {
            while (TIMES--) p.applyEffect(xmlstring);
        }
        return p;
    }
    function getCenterBounds(op) {
        var originalMinSize = getMinVisibleSize(op.visibleBounds);
        var p = applyOffset(op, false);
        if (getMinVisibleSize(p.visibleBounds) > originalMinSize) {
            // in some cases, path p becomes larger for some unknown reason
            p.remove();
            p = applyOffset(op, true);
        }
        var b = p.visibleBounds;
        if (getMinVisibleSize(b) > 10) {
            activeDocument.selection = [p];
            executeMenuCommand("expandStyle");
            p = activeDocument.selection[0];
            if (p.typename == "CompoundPathItem") {
                b = findBestBounds(op, p);
            }
        }
        p.remove();
        return b;
    }
    function add_nums(xy, s) {
        var txt = NUM_LAY.textFrames.add();
        txt.contents = ' ';
        txt.textRange.justification = Justification.CENTER;
        txt.textRange.characterAttributes.size = s;
        txt.position = [xy[0] - txt.width / 2, xy[1] + txt.height / 2];
        allNumLabels.push(txt);
    }
    function strokeComPath(compoundPath) {
        var p = compoundPath.pathItems,
            l = p.length,
            i = 0;
        for (; i < l; i++) {
            p[i].closed = true;
            p[i].stroked = true;
            p[i].filled = false;
        };
    }
})();

 

I would be interested in how it can be solved. I'm wondering if an analysis of bounding boxes and center points and relationships between nearby 'nodes'. Hmm.

- Mark

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
New Here ,
Nov 09, 2021 Nov 09, 2021

Copy link to clipboard

Copied

WOW! Mark that is amazing!. that's the closest I have seen it to perfect. 

So the numbers are needed in some sort of order because customers or templaters can specify which parts are required or need changing so as long as they aren't totally random it would work!.

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
Enthusiast ,
Nov 10, 2021 Nov 10, 2021

Copy link to clipboard

Copied

LATEST

Oh that's great that it'll work for you. 🙂

- Mark

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