Copy link to clipboard
Copied
I'm starting a sticker printing business using Illustrator as my main layout and illustration too. I was wondering if there's a script available for automatically arranging a set of elements on a page so that they optimally take up the available space. I figured this would save me some on material costs.
If I were to create a script from scratch, can someone give me pointers? I'm a casual AI user but I have Javascript experience.
Thanks.
Copy link to clipboard
Copied
Look for a Packing script but don't get your hopes up.
Copy link to clipboard
Copied
I would agree with Larry this is intensive math work… and you will very lucky to find anything that doesn't require payment for… I would also expect this to be done with plug-in over script unless you only need to pack basic shapes… Jongware may have pointers it would be way over my head… Don't know of anything already about sorry…
Copy link to clipboard
Copied
this is the holly grail of optimization, in the garment industry there are similar requirements for laying out the jeans pattern pieces to save on fabric, and big companies have developed automated systems for it...but word says it is never as good as a human...but it works wonders for making pillows.
Copy link to clipboard
Copied
I did object collision once… cost me an R1… ouch
Copy link to clipboard
Copied
Thanks everyone. Yeah, I was afraid it would involve math-instensive stuff. I guess for now I will do it all manually.
Copy link to clipboard
Copied
@ RigRutgers , Larry G. Schneider, Muppet Mark, CarlosCanto,
Hello everyone,
I would like to kindly ask if someone would post a screen capture or two demonstrating a few examples, using just basic outlines of shapes (I presume manually assembled), for a common simple example and a more involved complex intense example of this principle and what the "would be" code should accomplish as an outcome, thus showing the outcome in the screenshot.
Many thanks everyone!
Copy link to clipboard
Copied
something like this, the image below is the desired end result. The idea is to accommodate all pieces as tight as possible to save on fabric.
Copy link to clipboard
Copied
Thanks CarlosCanto, I really appreciate your response. I understood the workings of this already but was curious if I was on the same page when I saw this thread. I was wondering how interwoven people were imagining for optimization, thanks for the picture and confirmation. Thanks again for your response.
To anyone's knowledge, does something commercial exist already for this with in Illustrator.
Copy link to clipboard
Copied
no idea if there is something for illustrator, I doub it. Are you giving it a shot? at writing up a program for simpler shapes peharps?
Copy link to clipboard
Copied
I was not able to find anything for working directly within Illustrator for true shape nesting. I was just curious as most the software I researched is an external 3rd party program that mostly deals with basically shape outlines, thus for CNC, etc., not so much for actual full graphics as in Illustrator, like was initially discussed here, stickers, packaging, printing, etc... of couse some prepress / printing workflows and softwares offer nesting, etc..
Not sure if I am giving it a shot even on a simple basis 😉 I just saw this thread the other day and was further curious about it. For basic shapes maybe, but for complex (even more than you showed in your screenshot) it would require a lot and I am not sure the Illustrator Scripting API itself has what it takes to do true shape nesting from a scripted approach, or could even get close beyond a basic style.
---
@ Mark Muppet you were able to do Object level Collision detection in Illustrator?
Copy link to clipboard
Copied
Did anyone ever find anything that can do this? I work in the print industry as well and packing objects on the artboard to best use the space still remains a mundane time consuming manual task. I'm looking for something like the Pack UV's tools common in 3D Software.
Does it exist? A script that could just calculate the bounding box of every selected object and pack them onto the artboard, with a padding amount.
s
Copy link to clipboard
Copied
Hi RigRutgers,
there is plenty of documentation for that kind of problem. If you are looking for a solution for rectangles and squares, I would advise you to search for the Lodi-Martello-Vigo TPRF (2BPRF) algorithm.
It is pretty simple to implement and works like a charm for rectangles.
You can download a VERY interesting document here...
If someone has a good solution (algorithm only, not script) for non rectangular objects, I'd enjoy to read it.
I hope it helped!
Copy link to clipboard
Copied
Thanks for that, although its a bit out of my league! I muddle through with my scripting but I'm not a programmer. I'm sure there's a wizz out there who could knock it up, come on peeps! Best fit multiple selections to artboard with x padding! The printing industry will love you...
S
Copy link to clipboard
Copied
Even for simple rectangles there is no fast and (remotely) good solution for "best" fit ... Yup, it's one of those famous "holy grail" problems.
bigjobfaceman wrote:
... something like the Pack UV's tools common in 3D Software ...
Are all of your shapes rectangular? Is rotating allowed? Through 90 degrees only, or at any angle?
bigjobfaceman wrote:
Best fit multiple selections ...
How would you select several objects, when some of themselves may consist of different objects? Every one on a separate layer? Every one grouped? Only "symbols"?
Copy link to clipboard
Copied
Damn those Holy Grails...
They are not all rectangular but could be treated as such, just the overall width and height of a selection (even if its an oval you could take the width and height).
They would be grouped or single elements..
s
Copy link to clipboard
Copied
miaoumix2013,
Thanks for this the link to the bin packing algorithm paper!
I hadn't realize just how complex of a problem 2D bin packing was until I started reading through it.
It looks like that paper has everything (and more) that you'd need to create a Holy Grail of scripts, or atleast a good approximation.
Its definitely a very academic paper and I think I need to brush up on my greek characters a bit, but its pretty exciting to have a resource like this.
I took your advice and googled Lodi-Martello-Vigo TPRF (2BPRF) and ran across this paper, another useful reference and quite a bit shorter. (Also more up to date)
I look forward to eventually taking a crack at this script when I'm a bit better versed in the prerequisites... though part of me hopes some one else beats me to the punch. 😄
Copy link to clipboard
Copied
Any progress here?
Copy link to clipboard
Copied
Hi
you could look at Plato from Esko as an option, plug in for illustrator.
they do charge like a wounded bull though, but they are top notch products
Copy link to clipboard
Copied
Thanks
Copy link to clipboard
Copied
We use a script to place our dies on an art board before sending them to get made. We managed to narrow the sizes down 4 different ones and the script for making them will automatically scale depending on the size of the artwork. This reduces waste of the material, and since it is automatic it makes work faster for the other artists. I'll be posting snippets shortly.
Copy link to clipboard
Copied
The below image shows the 4 different die sizes, the artwork fits inside the dotted box so make sure that we have room around the die and the drill holes are assigned as well.
The name of each die is listed above it, and the size is listed below it.
The script is set to take each die and place it on the template until it is full, then it will save it and move it to the folder where it will be grabbed and preped for printing.
Everything below the **** is the script.
*******************************************************************************************************************************************************************
#target illustrator
var tempDoc = app.activeDocument;
copy();
if (tempDoc.selection.length > 0)
{
var myFile = File("S:/TEMPLATES/IN USE/DB_TEMPLATE.ai");
app.open(myFile);
var thisDoc = app.activeDocument;
thisDoc.views[0].centerPoint = [324,503];
thisDoc.views[0].zoom = .65;
var allGroups;
var horizontalCords = [0,180,360,540,0,180,360,540,0,180,360,540,0,180,360,540,0,180,360,540,0];
var verticalCords = [1012.5,1012.5,1012.5,1012.5,810,810,810,810,607.5,607.5,607.5,607.5,405,405,405,405,202.5,202.5,202.5,202.5,202.5];
var oneGroups = new Array();
var twoGroups = new Array();
var oneAGroups = new Array();
var twoAGroups = new Array();
var makeNew1 = new Array();
var makeNew2 = new Array();
var twoACounter = 0;
var layerRemainder = [4,4,4,4];
var totalDies = 0;
var noGo = 0;
var caseTest;
if (thisDoc.pageItems.length == 0)
drawTemplate();
var newLayer = thisDoc.layers.add();
newLayer.name = "Die Layer";
paste();
allGroups = thisDoc.groupItems;
for (i=0;i<allGroups.length;i++){// determine what dies are present
if (allGroups.name == "1"){
oneGroups.push(allGroups);
}
else
if (allGroups.name == "1A"){
oneAGroups.push(allGroups);
}
if (allGroups.name == "2") {
twoGroups.push(allGroups);
}
else
if (allGroups.name == "2A"){
twoAGroups.push(allGroups);
}
}// end FOR
if (oneAGroups.length == 1)
oneAGroups[0].position = [540,101.5];
if (twoAGroups.length == 1)
twoAGroups[0].position = [360.25,101.25];
if (oneAGroups.length == 1 && twoAGroups.length == 1)
oneAGroups[0].position = [360,203.5];
if(oneAGroups.length == 2){
var add1Group = thisDoc.groupItems.add();
add1Group.name = "1";
oneAGroups[0].name = "1A changed";
oneAGroups[1].name = "1A changed";
oneAGroups[0].position = [0,0];
oneAGroups[1].position = [0,-100.75];
oneAGroups[0].moveToBeginning(add1Group);
oneAGroups[1].moveToBeginning(add1Group);
oneGroups.push(add1Group);
oneAGroups.length = 0;
redraw();
}
if(twoAGroups.length == 2){
var add2Group = thisDoc.groupItems.add();
add2Group.name = "2";
twoAGroups[0].name = "2A changed";
twoAGroups[1].name = "2A changed";
twoAGroups[0].position = [0,0];
twoAGroups[1].position = [0,-100.75];
twoAGroups[0].moveToBeginning(add2Group);
twoAGroups[1].moveToBeginning(add2Group);
twoGroups.push(add2Group);
twoAGroups.length = 0;
redraw();
}
if (twoGroups.length > 0){
var h = 0;
var v = 0;
var dieCount = 0;
for (i = 0; i < twoGroups.length; i++) {
twoGroups.position = [horizontalCords
h = h + 2;
v = v + 2;
dieCount++
}//end FOR
}// end twoGroups length IF
if (oneGroups.length > 0){
var h = 0+(twoGroups.length*2);
var v = 0 + (twoGroups.length*2);
for (i = 0; i < oneGroups.length; i++){
oneGroups.position = [horizontalCords
h = h +1;
v = v + 1;
}// end FOR
}// end onGroups IF
redraw();// redraws template so it updates changes on the page
//thisDoc.close(SaveOptions.SAVECHANGES);
}// end noGo
else
alert("You have nothing selected...");
totalDies = (oneGroups.length + (twoGroups.length*2) + (twoAGroups.length/2) + (oneAGroups.length/2));
if (totalDies < 20)
{
caseTest = 0
}
else if (totalDies > 20)
caseTest = 1
else if (totalDies == 20)
caseTest = 2;
switch (caseTest)
{
case 0:
thisDoc.close(SaveOptions.SAVECHANGES);
break;
case 1:
alert ("Die will not fit on the Template at this time. Try again later.");
thisDoc.close(SaveOptions.DONOTSAVECHANGES);
break;
case 2:
var answer = confirm ("The Template is full. Do you want to clear it?");
if (answer == true)
printTheTemplate();
break;
}
function drawTemplate(){ //draws the template if the page is empty
var tempDoc = app.activeDocument;
tempDoc.rulerOrigin = [0,0];
tempDoc.pageOrigin = [0,0];
var newLayer = tempDoc.layers.add();
newLayer.name = "Template Layer";
var templateGroup = tempDoc.groupItems.add();
templateGroup.name = "Template Build";
var vertLoc = .25;
var horzLoc = -.25;
var topTemp = new Array();
var botTemp = new Array();
var leftTemp = new Array();
var rightTemp = new Array();
for (i=0;i<5;i++){
botTemp = thisDoc.pathItems.rectangle(0,vertLoc,.5,21);
topTemp = thisDoc.pathItems.rectangle(1033,vertLoc,.5,21);
botTemp.moveToBeginning(templateGroup);
topTemp.moveToBeginning(templateGroup);
vertLoc = vertLoc + 180;
}
for (j=0; j<6;j++){
leftTemp
rightTemp
leftTemp
rightTemp
horzLoc = horzLoc +202.5;
}
return
}// end function drawTemplate
function printTheTemplate()
{
// October 16, 2012 Henry J. Klementovich
//var TemplatePath = File("C:/Users/henryk/Desktop/Illustrator Test Files/HS_TEMPLATE.ai");
//open(TemplatePath)
//open(myFile);
var thisDoc = app.activeDocument;
thisDoc.rulerOrigin = [0,0];
thisDoc.pageOrigin = [0,0];
var thePath = ("S:/TEMPLATES/PRINTED");
// Will only continue if the artist has selected the art. This step saved a lengthy FOR loop that would have had to select each page or path item of the
// document. Some of the templates had over 5,000 items, resulting in an un-exceptable wait-time for the loop to select them.
for (x=0;x<thisDoc.groupItems.length;x++)
thisDoc.groupItems
if (thisDoc.selection.length > 0)
{
// This section pulls the date from the system for two purposes: the date shown on the template and the date used to save the file to the ArtShare.
// They are different b/c system filenames cannot include the ":" char, which is used on the template for the time object.
var theDate = new Date();
var day = theDate.getDate();
var month = theDate.getMonth() + 1;
var year = theDate.getFullYear();
var hours = theDate.getHours();
var min = theDate.getMinutes();
if (min < 10)
min = ("0" + min);
var morn;
if (hours >= 12)
{
hours = hours - 12;
morn = " PM";
}
else
morn = " AM"
var saveDate = (month + "-" + day + "-" + year + " " + hours + min + morn );
var tempDate = thisDoc.textFrames.add();
tempDate.name = theDate;
tempDate.contents = (month+ "/" + day + "/ " + year + " " + hours + ":" + min );
tempDate.top = 1026;
tempDate.left =40;
tempDate.filled = true;
var actGroups = thisDoc.selection;
var artGroup = thisDoc.groupItems.add();
artGroup.name = "Art Group";
for (i=0;i<actGroups.length;i++)
actGroups.moveToEnd(artGroup);
tempDate.moveToEnd(artGroup);
artGroup.selected = true;
copy();
thisDoc.pageItems.removeAll();// copies everything from the current template into the clipboard, clears the template, saves it and closes it.
var layLen = app.activeDocument.layers.length;
//alert(layLen);
for (i=0;i<layLen;i++)
app.activeDocument.layers[0].remove();
thisDoc.close(SaveOptions.SAVECHANGES);
app.documents.add();// adds new document for the template to be saved in the Printed folder.
paste();
var thisDoc = app.activeDocument;
var saveName = new File (thePath + "/" + saveDate);
saveOpts = new IllustratorSaveOptions();
saveOpts.compatibility = Compatibility.ILLUSTRATOR13;
saveOpts.generateThumbnails = true;
saveOpts.preserveEditability = true;
thisDoc.saveAs( saveName, saveOpts );
var actGroups = thisDoc.selection;
copy();
thisDoc.close(SaveOptions.SAVECHANGES);
$.sleep(10);
app.documents.add();
paste();
var nexDoc = app.activeDocument;
var actGroups = nexDoc.selection;
var artGroup =nexDoc.groupItems.add();
artGroup.name = "Art Group";
for (i=0;i<actGroups.length;i++)
actGroups.moveToEnd(artGroup);
//artGroup.selected = true;
artGroup.resize(70,70);
alert("The current template has been saved to the Printed Templates folder. This page is to be printed and sent to editing.")
}
}
***************************************************************************************************************************
Hope this helps someone get one created because if they can make one that doesn't depend on the premade dies that would help me out quite a bit because some of the dies that we make are an odd size so we have to place them manually.
Copy link to clipboard
Copied
This is the image of the finished product, all the ones that are auto placed are colored with an orange box, the ones that must be placed manually are brown. The colors help people understand which ones need to be moved a lot easier. I've removed the art files from the boxes as some of them are copyrighted so you can only see the boxes for this file.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now