#target illustrator if (app.documents.length === 0) { alert("No document open"); exit(); } var doc = app.activeDocument; // ================= UI ================= var win = new Window("dialog", "CTP Optimizer v3 – Mixed Calculation"); win.alignChildren = "fill"; // Sheet var pSheet = win.add("panel", undefined, "Sheet Size"); pSheet.add("statictext", undefined, "Format: 11x14 in | 28x35 cm | 450x320 mm"); var sheetInput = pSheet.add("edittext", undefined, "11x14 in"); sheetInput.characters = 20; // Margin var pMargin = win.add("panel", undefined, "Margins (mm)"); pMargin.orientation = "grid"; pMargin.add("statictext", undefined, "Left"); var mL = pMargin.add("edittext", undefined, "10"); pMargin.add("statictext", undefined, "Right"); var mR = pMargin.add("edittext", undefined, "10"); pMargin.add("statictext", undefined, "Top"); var mT = pMargin.add("edittext", undefined, "10"); pMargin.add("statictext", undefined, "Bottom"); var mB = pMargin.add("edittext", undefined, "10"); // Gap var pGap = win.add("panel", undefined, "Gap"); pGap.orientation = "row"; pGap.add("statictext", undefined, "Gap between items (mm):"); var gapInput = pGap.add("edittext", undefined, "5"); // Quantity var pQty = win.add("panel", undefined, "Mixed Quantity (Size-Qty)"); var qtyInput = pQty.add("edittext", undefined, "S-1\nM-2\nL-2\nXL-1", {multiline:true}); qtyInput.preferredSize.height = 100; // Result var pRes = win.add("panel", undefined, "Result"); var resTxt = pRes.add("edittext", undefined, "", { multiline:true, readonly:true }); resTxt.preferredSize.height = 220; // Buttons var btns = win.add("group"); var calcBtn = btns.add("button", undefined, "Calculate"); var copyBtn = btns.add("button", undefined, "Copy"); var pdfBtn = btns.add("button", undefined, "Export PDF"); btns.add("button", undefined, "Close", {name:"cancel"}); // ================= FUNCTIONS ================= function parseSheet(str) { var unit = "in"; if (/mm/i.test(str)) unit = "mm"; if (/cm/i.test(str)) unit = "cm"; var n = str.match(/([\d\.]+)\s*x\s*([\d\.]+)/i); if (!n) return null; var w = parseFloat(n[1]); var h = parseFloat(n[2]); if (unit === "mm") { w *= 2.8346; h *= 2.8346; } else if (unit === "cm") { w *= 28.346; h *= 28.346; } else { w *= 72; h *= 72; } return {w:w, h:h}; } function buildMix(qtyMap, capacity) { var sheets = []; while (true) { var sheet = {}; var filled = 0; for (var k in qtyMap) { while (qtyMap[k] > 0 && filled < capacity) { sheet[k] = (sheet[k] || 0) + 1; qtyMap[k]--; filled++; } } if (filled === 0) break; sheets.push(sheet); } return sheets; } // ================= LOGIC ================= calcBtn.onClick = function () { if (doc.selection.length === 0) { alert("Please select one design object"); return; } var sheet = parseSheet(sheetInput.text); if (!sheet) { alert("Invalid sheet format"); return; } var gap = parseFloat(gapInput.text) * 2.8346; var ml = parseFloat(mL.text) * 2.8346; var mr = parseFloat(mR.text) * 2.8346; var mt = parseFloat(mT.text) * 2.8346; var mb = parseFloat(mB.text) * 2.8346; var usableW = sheet.w - ml - mr; var usableH = sheet.h - mt - mb; var b = doc.selection[0].visibleBounds; var dW = b[2] - b[0]; var dH = b[1] - b[3]; var col = Math.floor((usableW + gap) / (dW + gap)); var row = Math.floor((usableH + gap) / (dH + gap)); var capacity = col * row; if (capacity <= 0) { alert("Design too large for sheet"); return; } var lines = qtyInput.text.split("\n"); var qtyMap = {}; var totalQty = 0; for (var i=0;i