Salta al contenuto principale
In questa pagina▾

Engine API

Se ti occupi solo di tagliare pannelli, questa pagina non ti serve. L’ottimizzatore dentro CutOptim fa già tutto quello che è descritto qui. L’Engine API è lo stesso motore senza uno schermo attaccato, per quando un altro software ha bisogno di piani di taglio senza che una persona apra l’app.

Tutto quello che CutOptim fa nel tuo browser parte da un solo calcolo: dati questi pezzi e questo materiale, qual è il modo migliore di tagliarli? L’Engine API espone esattamente quel calcolo su internet, così un programma diverso può porre la domanda e riavere la risposta — senza browser, senza clic, senza che nessuno abbia fatto l’accesso.

È tutta l’idea. Non è un nuovo ottimizzatore, non è un ottimizzatore migliore e non è un livello di abbonamento superiore. È lo stesso motore, raggiungibile da un software invece che da una persona.


Fa per me?

Per la grandissima maggioranza degli utenti di CutOptim, la risposta onesta è no. Se la tua giornata di lavoro consiste nell’aprire CutOptim, inserire pezzi e materiale e stampare o esportare il piano, l’app è il prodotto e questa pagina non ti riguarda.

L’Engine API serve a una sola situazione: i piani di taglio devono comparire dentro un software che già usi, senza che nessuno visiti CutOptim. In pratica si tratta di uno di questi due casi:

  • Usi già un software dentro cui il piano di taglio dovrebbe stare. Un ERP che tiene i tuoi ordini, uno strumento di preventivazione che calcola il prezzo dei lavori, o il software della macchina stessa. Invece di far ribattere a un operatore la stessa distinta di pezzi in CutOptim, quel programma interroga direttamente il motore e mostra il piano dove il lavoro avviene già.
  • Ti stai facendo sviluppare un software. Da uno sviluppatore interno, da una software house locale o dal fornitore della tua macchina. L’Engine API è ciò a cui si collegano.

Usare l’Engine API significa che qualcuno scrive del software che la richiama. Non c’è nessuna interfaccia, nessun foglio di calcolo da compilare e niente da installare — è un servizio per programmi, e il lavoro lo fa chi scrive quel programma. Se dalla tua parte nessuno scrive codice, l’app è quello che ti serve.

Se non sei sicuro da quale lato di quella linea ti trovi, una buona prova: il piano potrebbe comparire senza che nessuno lo chieda? Se sì, l’API è pertinente. Se è sempre una persona a decidere di fare un piano di taglio, l’app è già lo strumento giusto.


Cosa fa

Il tuo software invia le stesse due cose che inseriresti nell’app — un elenco di pezzi e un elenco di materiale — in JSON. Il motore restituisce una risposta completa:

  • Lo schema completo. Ogni pezzo, posizionato su un pannello o su una barra precisi, compresa l’indicazione se è stato ruotato.
  • Un piano di taglio. Non solo un disegno di rettangoli: la vera sequenza di taglio guillotine, in ordine, così che il piano possa essere eseguito su una sezionatrice.
  • I numeri. Quanti pannelli o barre richiede il lavoro, la percentuale di resa, quanti tagli servono e il prezzo totale del materiale usato. Per i pannelli ottieni anche i due conteggi onesti dei tagli — le linee di taglio, che uniscono i tagli che condividono un’unica regolazione della guida, e i passaggi della lama, che contano ogni singolo passaggio — più la lunghezza totale tagliata.
  • Opzionalmente, il disegno. Chiedi include: ["svg","csv","dxf"] e la risposta trasporta anche lo schema come file già pronto — un disegno SVG 2D autonomo, un DXF R12/AC1009 o una distinta di taglio CSV — inline nel JSON, senza archiviazione e senza una seconda chiamata. (L’SVG è solo 2D.) Nelle richieste 2D puoi chiedere anche labels (dati di etichetta per pezzo), planHash (un’impronta del piano), pdf (il PDF del piano di taglio) e labelsPdf (il PDF delle etichette): i PDF in base64, disegnati con lo stesso codice dell’app.
  • I tuoi identificativi, restituiti. Allega un oggetto meta — un codice articolo, una riga d’ordine, un riferimento cliente — a qualsiasi pezzo o riga di materiale, e torna invariato su ogni pezzo posizionato e su ogni pannello o barra, così il piano si allinea con il tuo sistema. È questo il campo da usare quando vuoi inviare tutti i tuoi pannelli, contrassegnare ciascuno con un tuo codice e rileggere quale pannello ha scelto l’ottimizzatore: metti il codice in stock[].meta e ti torna su sheets[].meta. Non influisce mai sul posizionamento. Non usare invece il campo material per identificare: material è una partizione rigida (un pezzo viene tagliato solo da righe di materiale con lo stesso valore material), quindi assegnare un material a ogni riga di materiale lasciando i pezzi senza tag fa tornare ogni pezzo come unmatched, con un risultato vuoto.

Le modalità di ottimizzazione sono quattro, tutte corrispondenti all’app — una per i pannelli 2D, una per il materiale 1D lineare come barre, profili e tubi, una per il legno, dove il materiale ha una sezione, e il nesting a forma reale (POST /v1/optimize/nest), che annida poligoni arbitrari per il taglio laser, plasma e a getto d’acqua (la modalità Nesting dell’app). Ogni endpoint di ottimizzazione ha anche un endpoint di validazione gratuito che verifica una richiesta senza risolverla (vedi sotto).

Endpoint

La base URL è https://api.cutoptim.com. Gli endpoint di ottimizzazione e usage portano una chiave in un header Authorization: Bearer <key>; gli endpoint di validazione e health non richiedono alcuna chiave.

Endpoint Cosa fa
POST /v1/optimize/2d ottimizzazione 2D per pannelli
POST /v1/optimize/1d ottimizzazione 1D / lineare — barre, profili, tubi
POST /v1/optimize/wood Ottimizzazione del legno — 1D con abbinamento della sezione
POST /v1/optimize/nest Nesting a forma reale — poligoni irregolari per laser, plasma e getto d’acqua
POST /v1/validate/2d · /1d · /wood · /nest Valida una richiesta senza risolverla — gratis, nessuna chiave, nessuna quota
GET /v1/jobs/{id} Interroga un lavoro asincrono del motore max — solo i tuoi lavori, nessuna quota
POST /v1/import/nest Legge i contorni dei pezzi da un file SVG o DXF — richiede una chiave, non consuma quota
GET /v1/usage consumo e quota dell’ACCOUNT nel mese corrente (tutte le chiavi ne condividono una)
GET /v1/health controllo di liveness — non richiede nessuna chiave

La maggior parte delle chiamate riceve direttamente il risultato finito. L’unica eccezione è il motore asincrono max (vedi Tre motori più sotto): un invio max restituisce un id di lavoro e interroghi GET /v1/jobs/{id} finché il piano non è pronto.

Gli endpoint di validazione prendono lo stesso corpo dell’endpoint di ottimizzazione corrispondente e lo verificano senza eseguire la risoluzione: una richiesta malformata torna come 400 che indica il campo esatto sbagliato, mentre una ben formata restituisce valid: true più avvisi di fattibilità (per esempio un pezzo che non entra in alcun materiale). Non costano nulla e non richiedono alcuna chiave, così puoi validare i tuoi payload mentre costruisci l’integrazione — ancora prima di avere una chiave — e confermare che una richiesta non verrà rifiutata senza spendere una delle tue chiamate mensili.

Direzione della venatura sui pannelli

Il compensato e i pannelli impiallacciati hanno una venatura, e un pezzo in vista deve essere tagliato con la venatura nel verso giusto. Su POST /v1/optimize/2d, invia grain su una riga di materiale — "w" o "h", il lato del pannello lungo il quale corre la venatura — e grain su un pezzo, il lato del pezzo che deve correre lungo di essa. Ogni pezzo così impostato viene posizionato con la venatura lungo quella del suo pannello: ruotato di 90° quando è quello che serve (rotated: true sul posizionamento, come per qualsiasi rotazione), e rotatable viene ignorato per esso. Un pezzo senza grain ruota comunque liberamente, anche su una riga di materiale senza grain (MDF, melaminico); un pezzo CON grain mantiene anche su una riga così l’orientamento che gli danno le righe venate — con material si tengono separati pannelli venati e lisci. Un pezzo che entrerebbe solo ruotato di 90° contro la venatura compare in unplaced nella misura inviata, una riga di warnings lo nomina e POST /v1/validate/2d lo segnala prima che si consumi una chiamata.

Nella stessa richiesta possono stare righe di materiale con la venatura in direzioni diverse — un 2440 × 1220 con "w" e un 1220 × 2440 con "h" — e ogni pannello torna nel verso della propria riga, con grain ripetuto in sheets[]. Con material, un pezzo è vincolato a una venatura solo se il suo materiale ha un pannello con venatura. Il grain di un pezzo, se nella richiesta non c’è materiale con venatura, non ha effetto, e una riga in warnings lo segnala. options.trim e un options.firstCut forzato valgono per ogni pannello nell’orientamento della propria riga, anche su una riga la cui venatura corre nell’altro verso. La modalità Direzione venatura dell’app CutOptim esegue lo stesso codice. (dal 2026-10-02)

Corrispondenza venatura sui pannelli (set abbinati)

La direzione della venatura tiene ogni pezzo con la venatura nel verso giusto. Alcuni frontali chiedono di più: un frontale di cassetto sopra due ante il cui disegno prosegue dall’uno all’altro, come se i tre fossero ancora un’unica tavola. Su POST /v1/optimize/2d, dai un id a quelle righe di pezzi e nominale in matchedSets:

{
  "parts": [
    { "id": "DF", "name": "Drawer front", "w": 48.125, "h": 6 },
    { "id": "DOOR", "name": "Door", "w": 24, "h": 30, "qty": 2 },
    { "name": "Shelf", "w": 22.5, "h": 11.25, "qty": 4 }
  ],
  "stock": [{ "w": 96, "h": 48, "qty": 2, "grain": "w" }],
  "options": { "kerf": 0.125 },
  "matchedSets": [
    { "id": "base-1", "name": "Base cabinet fronts", "grain": "w",
      "layout": { "dir": "rows", "lines": [["DF"], ["DOOR", "DOOR"]] } }
  ]
}
  • Che cos’è un set. layout.lines elenca i membri per parts[].id. Con dir: "rows" ogni linea è una riga di membri affiancati e le righe si impilano dall’alto in basso, quindi [["DF"], ["DOOR", "DOOR"]] è un frontale di cassetto sopra due ante; con "cols" ogni linea è una colonna e le colonne stanno affiancate. Un pezzo può comparire più volte in uno stesso set (Anta, Anta), ma può appartenere a un solo set. qty (predefinito 1) è il numero di istanze che ti servono — tre mobili identici sono qty: 3 — e il qty dei pezzi stessi deve coprire ogni istanza. Un set ha almeno 2 e al massimo 24 membri, e una richiesta accetta al massimo 50 set.
  • Come viene tagliato. Il set attraversa l’ottimizzatore come un unico rettangolo — il blocco — e torna come i suoi membri, esattamente a un kerf di distanza, ricavati da un unico pezzo di pannello. Il grain del set ("w" o "h", lungo la larghezza o l’altezza del blocco) decide la direzione di ogni membro; il grain di un singolo membro non viene usato all’interno del set, e un avviso nomina ogni membro che sovrascrive. Senza grain del set, il blocco può ruotare quando ogni membro è rotatable. installGap è la fuga tra i membri sul mobile (predefinita: il kerf); sul pannello restano comunque a un kerf di distanza.
  • Cosa torna. Ogni membro posizionato porta matchedSet: l’id del set, quale instance e la sua position in ordine di lettura sul fronte del mobile — dall’alto in basso, da sinistra a destra, a partire da 1 — più un hint come "left" o "right" dove non è ambiguo. La risposta aggiunge un riepilogo matchedSets, una voce per set: la sua letter (A, B … nell’ordine della richiesta), quante istanze sono state tagliate come un unico blocco (asBlock), divise o lasciate non posizionate, la dimensione del blocco e i warnings del set. Quando un blocco non entra in nessun pannello, onMiss: "split" (il predefinito) posiziona i membri uno a uno con un avviso, e onMiss: "unplaced" li elenca in unplaced.
  • Avvisi, non errori. Una misura che non combacia è un avviso sul set, non un rifiuto. Ogni riga inizia con il suo codice — align: (le linee non sono a filo), gap: (il kerf è più largo di installGap), grain:, split:, unplaced:, unmatched: (nessuno stock del materiale del set), priority: e grainGroup: — e align e gap sono valutati a 1/64 della tua unità o a un quarto di kerf, il minore dei due. Un set che non si può disporre affatto — un id di membro che nessun pezzo porta, un id referenziato su due pezzi, meno di due membri, troppo pochi pezzi per qty — è un 400 che nomina il campo esatto, prima che una chiamata venga addebitata.
  • parts[].id si può inviare senza rischi. Viene controllato solo un id a cui un set fa riferimento (una stringa stampabile non vuota di al massimo 64 caratteri, oppure un intero, su esattamente un pezzo). Ogni altro id viene ignorato, qualunque cosa contenga, quindi i codici articolo del tuo ERP possono restare sulle righe. E nulla cambia per una richiesta senza set: solo un array matchedSets non vuoto attiva la funzione — assente, null, [] o un valore che non è un array riceve esattamente la risposta di prima.
  • Export. Con i set, csv guadagna le colonne Set e Position in fondo, svg stampa il codice di posizione (A1, A2 …) nelle etichette dei pezzi e disegna la cornice di ogni set in un gruppo matched-sets separato — options.setOutlines: false lascia fuori quel gruppo — e dxf porta il codice di posizione sul layer LABELS. pdf e labelsPdf non contrassegnano i set: disegnano i membri come pezzi ordinari, e warnings lo dice; i segni dei set sono in sheets[].parts[].matchedSet, csv e svg.
  • Motori ed endpoint. I motori heuristic e balanced dispongono i set (balanced non ordina per priority, quindi con respectStock un set può perdere lì il suo posto, con un avviso priority:). Il motore max rifiuta un matchedSets non vuoto con un 400 il cui details.unsupported lo nomina, prima che una chiamata venga addebitata; uno vuoto è un normale lavoro max. matchedSets e parts[].id valgono solo per il 2D: gli endpoint 1D, wood e nest li ignorano.
  • grainGroup è deprecato. È ancora accettato e funziona esattamente come prima: i pezzi che condividono un gruppo restano su un unico pannello. Non li ha mai posizionati uno accanto all’altro, quindi non dà una venatura continua tra di loro — per quello usa matchedSets.

La Corrispondenza venatura dell’app CutOptim dispone i set con lo stesso nucleo.

Perché il legno ha un endpoint dedicato

Il materiale lineare conosce una sola dimensione, la lunghezza, quindi qualsiasi barra può servire qualsiasi pezzo. Con il legno non funziona così: un pezzo 50×150 non può uscire da una barra 50×100, per quanta lunghezza avanzi. L’endpoint del legno prende perciò entrambi i lati della sezione su ogni pezzo e ogni riga di materiale, divide il lavoro per sezione, abbina a ciascuna sezione il proprio materiale e restituisce le sezioni separatamente — ognuna con le proprie barre e i propri totali, accanto ai numeri dell’intero lavoro.

Due dettagli da conoscere prima di integrarlo:

  • I due lati della sezione si possono inviare in qualsiasi ordine. 50×100 e 100×50 sono la stessa trave girata e vengono trattate come un’unica sezione. Così una differenza nel modo in cui i tuoi dati sono stati inseriti non può far sparire del materiale.

  • «Nessun materiale di questa sezione» e «non è entrato» sono segnalati separatamente. Il primo è un problema di materiale mancante, il secondo di capacità, e si risolvono in modi diversi — mescolarli in un unico elenco manderebbe il tuo utente a cercare nel posto sbagliato.

Potresti approssimare tutto questo con più chiamate 1d tue, raggruppando i pezzi da solo. Ti costerebbe una richiesta di quota per sezione invece di una per il lavoro, sposterebbe l’abbinamento del materiale nel tuo codice e produrrebbe un totale che dovresti comporre tu — e che non coinciderebbe necessariamente con quanto l’app CutOptim mostra per lo stesso lavoro.


Pezzi da un file CAD

L’endpoint di nesting non accetta solo coordinate. Un pezzo può portare invece un source — un documento SVG o DXF — e il server ne estrae il contorno, e gli eventuali fori, dal file. È lo stesso lettore che l’app usa quando trascini un disegno sulla sua modalità Nesting, quindi una libreria di pezzi che esiste già come file CAD non va prima riscritta in elenchi di coordinate.

Il file sostituisce solo la geometria. Quantità, materiale, rotazioni ammesse e i tuoi metadati restano campi ordinari della riga del pezzo, esattamente come quando invii coordinate. Un file descrive un pezzo; quando un singolo disegno contiene più componenti separati, POST /v1/import/nest lo divide prima in righe pronte — e quella chiamata richiede una chiave ma non consuma una richiesta della tua quota mensile.

Nulla viene memorizzato. Il file esiste solo come la richiesta stessa: viene letto in memoria e sparisce nel momento in cui la risposta è scritta. Non resta copia su disco o in un database, nulla finisce in un log e non c’è nulla da cancellare dopo. Con le unità facciamo lo stesso — un DXF può dichiarare millimetri o pollici e noi riportiamo ciò che ha detto, ma le coordinate non vengono mai convertite, perché nessun valore di questa API porta un’unità.

Sempre la stessa risposta

Il motore è deterministico: lo stesso input produce sempre lo stesso output. Non c’è casualità e non c’è nessun orologio dentro l’algoritmo.

Suona accademico, ma è la ragione pratica per costruirci sopra. Significa che i risultati possono essere messi in cache — se hai già chiesto di questo lavoro esatto, puoi riutilizzare la risposta in sicurezza invece di richiederla di nuovo. Significa anche che l’integrazione può essere testata: un piano può essere confrontato con un risultato noto come corretto, e una differenza è una differenza reale, non rumore. Un software che lunedì preventiva un prezzo a un cliente, venerdì preventiverà lo stesso prezzo.

C’è un’unica eccezione opt-in, e lo dichiara: il motore max per il nesting (sotto) impiega un budget di tempo fisso per cercare, quindi quanto arriva lontano dipende da quanto lavoro entra in quel tempo. Le sue risposte portano deterministic: false. Ogni altro motore — incluso il predefinito del nesting, lbf — è deterministico.

Riprovare in sicurezza. Se la connessione cade, non si sa se la richiesta è arrivata. Inviate un’intestazione Idempotency-Key — un valore che scegliete per ogni lavoro — e riprovate con la stessa chiave: entro 24 ore la stessa richiesta restituisce la risposta salvata, segnata con Idempotency-Replayed: true, e non viene addebitata una seconda volta. Anche un lavoro max non viene accodato due volte. La chiave demo pubblica ignora questa intestazione. (Dal 2026-10-15.)

Webhook per i job asincroni. Invece di interrogare GET /v1/jobs/{id}, registrate un endpoint (un URL https://) nella dashboard e ricevete un POST firmato — job.succeeded o job.failed — quando un job max asincrono termina. Verificate l’intestazione CutOptim-Signature con il segreto ricevuto, rispondete entro 10 secondi e leggete il piano con GET /v1/jobs/{id}. Una consegna non riuscita viene ritentata: 8 tentativi in 24 ore. (Dal 2026-10-19.)

SDK ufficiali. Client open source per TypeScript, Python e PHP — npm install @cutoptim/engine, pip install cutoptim, composer require cutoptim/engine — con richieste tipizzate, tentativi che non vengono mai addebitati due volte (ogni chiamata porta un Idempotency-Key), un aiuto per attendere i job asincroni e la verifica dei webhook. Codice su GitHub; dettagli nella guida agli SDK (in inglese).

Server MCP per assistenti IA. Claude Code, Cursor, VS Code e Claude Desktop possono chiamare il motore come strumenti tramite il server Model Context Protocol ospitato su https://api.cutoptim.com/mcp, con la stessa chiave API (Authorization: Bearer …) e la stessa quota: una chiamata a uno strumento è una chiamata API, e gli strumenti validate_* sono gratuiti. Gira anche in locale con il pacchetto npx -y @cutoptim/mcp (chiave in CUTOPTIM_API_KEY), e il MCP Registry ufficiale lo elenca come io.github.cutoptim/engine. Le configurazioni dei client sono nella guida MCP (in inglese).


Tre motori

L’API offre la scelta del motore. I primi due funzionano in modo sincrono; il terzo è asincrono. La differenza non è la qualità — è un compromesso tra velocità, realizzabilità del risultato su una sezionatrice e quanto ci si avvicina al minimo teorico.

  • heuristic è il predefinito ed è lo stesso che usa l’app. Produce schemi guillotine: resa massima, ogni schema tagliabile su una sezionatrice, e sempre un piano di taglio completo. Sincrono.
  • balanced si attiva su richiesta. Usa invece il nesting libero, che è enormemente più rapido sui lavori molto grandi — misurato circa 25× più rapido su un lavoro da 2.000 pezzi — al costo di una resa leggermente inferiore. L’insidia importante: i suoi schemi spesso non sono tagliabili da bordo a bordo, quindi per quelli non restituisce alcun piano di taglio. Sincrono.
  • max si attiva su richiesta, per i pannelli 2D (e, separatamente, per il nesting a forma reale — vedi sotto). Sul 2D è una ricerca ad albero lato server che raggiunge l’ottimo dimostrato su molti più lavori rispetto al predefinito, e i suoi schemi restano tagliabili a guillotine. Il costo è il tempo: una risoluzione max richiede da secondi a un minuto, quindi non risponde nella risposta. Invece, POST /v1/optimize/2d con engine: "max" restituisce un id di lavoro, e interroghi GET /v1/jobs/{id} finché non è pronto. Rimane deterministico. Ricorri a esso quando un lavoro grande e di valore vale l’attesa per gli ultimi pannelli. Modella un solo formato di stock a piena dimensione con disponibilità illimitata, quindi una richiesta che porta anche un secondo formato di stock, trim per lato, stock limitato (respectStock), materiali, gruppi di venatura o un matchedSets non vuoto viene rifiutata in anticipo con un 400 che indica esattamente ciò che non può fare — prima che una chiamata venga addebitata. Manda quei lavori a heuristic, che li modella tutti.

Nesting: lbf e max

Il nesting a forma reale ha due motori propri. lbf è il predefinito: istantaneo, sincrono e deterministico. max si attiva su richiesta ed è asincrono, esattamente come il max 2D — POST /v1/optimize/nest con engine: "max" restituisce un id di lavoro, e interroghi GET /v1/jobs/{id}.

Il max per il nesting esegue prima il passaggio lbf, così ha sempre una risposta valida in mano. Poi impiega un budget di tempo (options.timeBudgetMs, 60 secondi per default, tra 10 e 180) cercando uno schema con meno pannelli, riempiendo un pannello alla volta. Non restituisce mai più pannelli di lbf: quando la ricerca non trova un miglioramento, ottieni lo schema lbf e un avviso che lo segnala. Poiché la ricerca è limitata nel tempo, le sue risposte portano deterministic: false. Accetta più dimensioni di pannello per materiale e respectStock, e classifica il proprio risultato con la stessa regola di lbf (sotto): sostituisce il piano lbf solo quando è migliore — mai solo perché ha meno pannelli. Un pannello poligonale o le zone di esclusione, che la sua ricerca a strisce non può modellare, vengono serviti dal passaggio lbf all’interno del lavoro, con un avviso — mai rifiutati. Il vecchio nome sparrow è accettato come alias di max.

I pezzi rettangolari ottengono una griglia esatta (dal 2026-09-28). lbf trova le posizioni per campionamento, e questo non cade quasi mai su una griglia senza alcun gioco: tre pezzi da 500 mm affiancati su un pannello da 1500 mm con spaziatura zero entrano esattamente, mentre una ricerca per campionamento ne posiziona due. Per questo entrambi i motori provano anche due alternative e mantengono quella che si classifica meglio con la stessa regola: i pezzi limitati agli angoli retti che consentono, e i rettangoli d’ingombro dei pezzi impacchettati da un algoritmo esatto per rettangoli (rettangoli che non si sovrappongono non possono contenere pezzi sovrapposti, quindi vale per qualsiasi contorno). A parità — stessi pannelli, stessa area di pannello — vince il piano che riempie i pannelli in ordine, dal primo all’ultimo, poi quello con meno pezzi fuori dagli angoli retti. Non c’è nulla da attivare, e secondo la classifica un risultato può solo migliorare; un piano che i rettangoli portano al minor numero di pannelli consentito dall’area dei pezzi fa anche rispondere max subito, invece di cercare.

Un lavoro di qualche decina di pezzi di solito richiede circa 15 secondi di budget (timeBudgetMs: 15000); il lavoro termina all’incirca uno o due secondi dopo il budget, più l’eventuale tempo trascorso in coda. Interroga GET /v1/jobs/{id} ogni due o tre secondi — interrogare non costa quota. Nessun budget può promettere un numero preciso di pannelli.

Nesting: distanza dal bordo, dimensioni del pannello e il costo di ogni pannello

  • Distanza dal bordo. options.minSeparation è la spaziatura tra i pezzi, e da sola si applica anche al bordo del pannello. options.edgeClearance imposta il bordo separatamente — per esempio 5 tra i pezzi e 0 o 10 al bordo. Omettilo e il bordo mantiene minSeparation, esattamente come prima. Funziona su entrambi i motori, richiede pannelli rettangolari (w e h), e le zone di esclusione mantengono minSeparation come i pezzi. Un pannello poligonale, o un valore che non lascia spazio su un pannello, viene rifiutato con un 400 prima che una chiamata venga addebitata.
  • Scegliere una dimensione di pannello. Quando un materiale ha due o più righe di materiale, lbf le prova nel tuo ordine, ogni dimensione da sola e in ordine dalla più economica, e tiene la migliore — quindi il risultato non dipende più dall’ordine in cui elenchi le righe. La classifica è: più pezzi da tagliare assolutamente posizionati (vedi sotto), poi più pezzi posizionati, poi minore area totale dei pannelli (materiale), poi meno pannelli. Con options.minimizeCost classifica invece in base al prezzo totale (price, o cost per una riga senza prezzo) — ma solo quando ogni riga di quel materiale ne porta uno; altrimenti ripiega sull’area e lo segnala in warnings.
  • Mescolare le dimensioni. Dopodiché, ogni pannello — a partire dal meno riempito — viene ri-annidato da solo sulle righe più economiche o più piccole, e sostituito quando l’intero piano classifica meglio. Così le dimensioni possono essere mescolate all’interno di un materiale: tipicamente due pannelli grandi e uno più piccolo per ultimo, dove l’ultimo pannello semi-vuoto un tempo era uno grande. Con options.respectStock, nessuna riga viene usata più spesso della sua qty. Il motore max applica la stessa classifica.
  • Pezzi da tagliare assolutamente. parts[].priority: true contrassegna un pezzo da tagliare assolutamente. Conta con options.respectStock — un materiale limitato, dove non tutti i pezzi potrebbero entrare: i pezzi da tagliare assolutamente vengono allora posizionati per primi, così un pezzo qualsiasi non si aggiudica mai lo spazio sul pannello di cui ha bisogno un pezzo da tagliare assolutamente, e ogni classifica qui sopra mette in testa il piano che ne mantiene di più, anche se posiziona meno pezzi in totale. Entrambi i motori lo rispettano (max mantiene lo schema lbf ogni volta che qualcosa resta senza posto). Senza respectStock ogni pezzo che entra viene comunque posizionato, quindi il flag non cambia nulla. Un pezzo da tagliare assolutamente che non entra in alcun pannello resta comunque elencato in unplaced. (Dal 2026-09-22 — prima il motore di nesting accettava il campo ma lo ignorava.)
  • Scorta limitata su cui non entra tutto. Con options.respectStock, quando il piano lascia ancora pezzi non posizionati, il motore riempie inoltre le lastre una alla volta con i rettangoli di ingombro dei pezzi — ognuna il più piena possibile, e un pezzo che entra in una sola misura di lastra va lì per primo (un fianco alto sull’unica lastra grande, non su una striscia di sfrido). Quel piano viene preso solo se posiziona più pezzi (prima quelli obbligatori) o usa meno materiale; un lavoro in cui entra tutto torna esattamente come prima. Rispetta le rotazioni ammesse di ogni pezzo, minSeparation ed edgeClearance. (Dal 2026-10-14.)
  • Il costo di ogni pannello. Ogni pannello porta stock — l’indice della riga di materiale della richiesta da cui è stato tagliato — e la risposta aggiunge stockUsage: una voce per ogni riga di materiale usata, con il suo numero di pannelli, il prezzo totale e la densità. L’unità è la riga di materiale, non la dimensione: due righe con le stesse dimensioni ma un prezzo o un meta diverso sono due voci.
  • Lunghezza di taglio e sfondamenti. Ogni pannello porta cutLength — la somma dei perimetri dei contorni e dei fori dei pezzi collocati, nella tua unità di misura — e pierces, uno per ogni contorno chiuso; metrics totalizza entrambi. È la lunghezza geometrica del contorno: nessun taglio a linea comune, ingresso lama o micro-giunto — li aggiunge il tuo CAM.
  • Area usata, per l’addebito di una parte di pannello. Ogni pannello porta usedWidth e usedHeight — il punto più lontano raggiunto da un pezzo collocato rispetto all’angolo di origine del pannello, nella tua unità di misura, sul pannello reale (con edgeClearance è incluso il margine al bordo) — e usedArea, il loro prodotto; stockUsage[].usedArea lo totalizza per riga di materiale. È ciò di cui un ERP ha bisogno per addebitare un taglio orizzontale (usedHeight × la larghezza del pannello), un taglio verticale (usedWidth × l’altezza del pannello) o il riquadro d’ingombro (usedArea) invece del pannello intero — la regola di addebito resta tua. Per rendere piccoli questi numeri, entrambi i motori compattano per default il pannello meno riempito di ogni materiale: i suoi pezzi vengono ri-annidati sullo stesso pannello con sottoinsiemi di rotazione tra quelli consentiti a ciascun pezzo — 0/180, 0/90/180/270 e un solo orientamento per ogni copia, incrociati con un allowedRotations discreto, mai un angolo nuovo — e viene mantenuto lo schema con l’area usata più piccola. Con engine: "max" quel pannello viene poi riposizionato anche dalla ricerca stessa — lungo l’altezza del pannello e, se il piano ha un solo pannello, anche lungo la larghezza — e si mantiene, con la stessa regola, lo schema più compatto. Il numero di pannelli, le dimensioni, il prezzo e i pezzi posizionati non cambiano mai; options.compact: false restituisce lo schema non compattato. Se addebiti una striscia invece del riquadro d’ingombro, imposta options.compactFor di conseguenza: "horizontal" mantiene lo schema con l’usedHeight più basso (una striscia sull’intera larghezza del pannello), "vertical" quello con l’usedWidth più piccolo (una striscia sull’intera altezza del pannello); il valore predefinito "box" mantiene l’usedArea più piccola. Le modalità a striscia provano anche ogni copia ruotata di un quarto (90° o 270°) dove allowedRotations lo consente. Quanto si riduce l’area usata dipende dai pezzi. (Dal 2026-09-22.)

balanced non significa «risultati migliori». È più rapido e rende leggermente meno, e quando il suo schema non è tagliabile a guillotine non c’è nessun piano di taglio da consegnare a chi sta alla sega. Scegli questo motore solo quando la velocità su un lavoro molto grande conta più di un piano pronto per la sega. Se hai dei dubbi, resta sul predefinito.


Limiti

Ogni richiesta ha dei limiti, così un lavoro fuori controllo fallisce in modo chiaro invece di rimanere bloccato:

Limite Valore
Pezzi per richiesta 2.000
Righe di materiale per richiesta 50
Dimensione del corpo della richiesta 1 MB
Dimensione del corpo della richiesta — percorsi nest che possono portare un disegno 10 MB
Chiavi attive per account 10
Chiamate validate senza chiave per indirizzo 120 / minuto
Chiavi API sconosciute per indirizzo 30 / minuto — poi 429 per il resto del minuto
Attesa di uno slot di calcolo libero (percorsi sincroni) circa 8 s — poi 429, nulla viene addebitato
Lavori max in queued/running per account 5
Budget di ricerca del max per il nesting, per lavoro 10–180 s (default 60 s)
Conservazione di Idempotency-Key 24 ore
Endpoint webhook per account 5
Tentativi di consegna webhook 8 in 24 ore

Ottenere l’accesso

Parti dalla pagina Engine API. L’Engine API è fatturata separatamente dai piani dell’app e nessun passaggio di piano la attiva.

  1. Prova, poi abbonati — oppure scrivici. Puoi chiamare l’API prima di pagare: i pulsanti Esegui questo esempio nel riferimento API usano una chiave demo pubblica, e qualsiasi account con accesso effettuato può creare chiavi di test gratuite dalla dashboard (una propria piccola quota mensile, mai fatturata, nessun abbonamento necessario). Quando sei pronto, abbonarsi dalla pagina Engine API è la via più rapida: il piano d’ingresso, Studio, parte con una prova gratuita e l’accesso arriva da solo sul tuo account. Se preferisci descrivere prima la tua integrazione, o ti serve un volume oltre il piano standard, scrivici e indica che cosa vuoi collegare e all’incirca quanti piani di taglio al mese servono.
  2. L’accesso viene aggiunto al tuo account. Nient’altro del tuo account cambia.
  3. Crea una chiave. La card chiavi API è nella tua dashboard per ogni account con accesso effettuato: senza abbonamento crea chiavi di test, con l’accesso API anche chiavi live. Le chiavi le crei, le nomini e le elimini lì tu stesso.
  4. Copia subito la chiave. La chiave completa viene mostrata una sola volta, nel momento in cui la crei.

Una chiave viene mostrata soltanto una volta. CutOptim ne conserva solo un hash sha256, mai la chiave stessa — quindi non è più rileggibile in seguito, né da te né da noi. Copiala subito nella configurazione del tuo software quando la crei. Se perdi una chiave, eliminala e creane una nuova; se una chiave viene esposta, eliminala e le chiamate smettono immediatamente di funzionare.

Tratta una chiave come una password: sta nella configurazione del tuo software, non in un’email, in un foglio di calcolo o in uno screenshot.

Che cosa fa la scheda Chiavi API nella dashboard

Quattro comandi, e vale la pena essere precisi su cosa cambia ciascuno — soprattutto l’ultimo, che molti si aspettano tocchi la fatturazione. Non la tocca.

  • Piano, cambio e fatturazione. Mostra il piano dell’account (Studio o Scale). Passa a Scale (o Passa a Studio) cambia il piano dopo una conferma, e la quota mensile dell’account cambia subito. Fatturazione apre le impostazioni di fatturazione, dove aggiorni la carta, vedi le fatture o disdici.
  • Crea chiave. Genera una nuova chiave e la mostra una volta sola, lì. Il nome (Integrazione ERP, staging) serve solo a distinguerle in seguito. Fino a 10 chiavi attive per account. Le chiavi di test si creano allo stesso modo e si contano a parte: hanno una propria piccola quota mensile e non vengono mai fatturate.
  • La barra di utilizzo. Due numeri: il totale del tuo account per il mese solare rispetto alla quota, e per ciascuna chiave quanto ha consumato. Il dato per chiave risponde a quale integrazione sta consumando il monte — non è un budget separato.
  • Revoca. Blocca quella singola chiave dalla chiamata successiva. La riga resta visibile, così lo storico non va perso.

Revocare una chiave non ha nulla a che vedere con l’abbonamento. Non disdice nulla, non rimborsa nulla e non libera quota — il piano continua e il monte resta, semplicemente non possiedi più quella chiave. Revoca quando una chiave è stata esposta o un’integrazione viene dismessa. Per smettere di pagare, disdici invece l’abbonamento: l’accesso prosegue fino alla fine del periodo già pagato e dopo smettono di funzionare anche le chiavi esistenti.

Una quota per l’account, non una per chiave

Ogni chiave attiva del tuo account attinge allo stesso monte mensile. Creare una seconda chiave non crea una seconda quota — le chiavi servono a separare staging e produzione, dare a ogni integrazione la propria credenziale e revocarne una senza disturbare le altre.

GET /v1/usage riporta la posizione dell’account (used, limit, remaining) e risponde quindi alla domanda che hai davvero — quanto resta prima che le chiamate falliscano — indipendentemente dalla chiave con cui hai chiesto. Esaurito il monte, ogni chiave restituisce 402, non solo quella che l’ha speso.


Piani, prezzo e quota

L’Engine API viene fatturata separatamente dai piani dell’app, ogni mese, in EUR, con due piani:

Piano Cosa cambia
Studio Il piano d’ingresso, con una prova gratuita
Scale Una quota mensile di richieste più ampia, senza prova — ci si arriva passando da Studio

Tutto il resto è uguale su entrambi: gli stessi motori, tutte e quattro le modalità, ogni opzione, le stesse risposte. Ogni richiesta conta allo stesso modo — un lavoro di nesting costa una richiesta, esattamente come uno 2D o 1D.

  • Limite rigido, nessun costo extra. Quando la quota mensile è esaurita, le chiamate restituiscono 402 fino al ripristino il primo giorno del mese successivo. Nessuna fattura a sorpresa.
  • Due email, perché il limite non ti colga di sorpresa. Inviamo un’email all’account al 90% della quota e di nuovo quando è esaurita.
  • Il cambio di piano si fa con un pulsante nella scheda Chiavi API della tua dashboard (Passa a Scale / Passa a Studio); la nuova quota si applica subito. Un upgrade viene addebitato subito per il resto del periodo; un downgrade non viene rimborsato e il prezzo più basso si applica dal prossimo rinnovo. Il cambio è disponibile al termine della prova.
  • Volumi maggiori del piano Scale vengono quotati individualmente — scrivici.

I prezzi e le quote attuali sono indicati sulla pagina Engine API — quella pagina li legge dalla nostra configurazione dei prezzi, quindi il dato è sempre quello corretto.

Per il dettaglio tecnico — la struttura esatta di richiesta e risposta, tutte le opzioni, tutti i codici di errore e come funziona il versionamento — vedi il riferimento API.


Componenti open source

I motori di CutOptim si basano su librerie open source, usate senza modifiche sui nostri server:

  • jagua-rs — il motore di collisione geometrica dietro il nesting a forma reale (MPL-2.0).
  • sparrow — la ricerca dietro il motore max per il nesting (MIT, KU Leuven).
  • PackingSolver — la ricerca ad albero dietro il motore max 2D (MIT).

Tutto ciò che le circonda — l’API, la corrispondenza tra il contratto e questi motori, i packer rettangolari e l’app stessa — è codice proprio di CutOptim.


Cosa non cambia

Vale la pena dirlo con chiarezza, perché l’Engine API si può facilmente fraintendere come un cambiamento del prodotto:

  • L’ottimizzatore nell’app è invariato. Gira ancora nel tuo browser, esattamente come prima.
  • Gratuito, Pro e Officina non sono toccati. Includono ancora l’ottimizzatore integrato nell’app, con gli stessi limiti di prima. Niente è stato spostato dietro l’API.
  • Niente di ciò che fai nell’app consuma richieste API. La quota API mensile viene toccata solo dalle chiamate che fa il tuo software.

L’Engine API è un’aggiunta per chi integra CutOptim in altri software. Se non è il tuo caso, non è cambiato niente.

FAQ

Che differenza c'è tra i piani Studio e Scale?
Solo il numero di richieste al mese e la prova. Entrambi i piani eseguono gli stessi motori, tutte e quattro le modalità e ogni opzione, e ogni richiesta conta allo stesso modo: un lavoro di nesting costa una richiesta, esattamente come uno 2D. Studio è il piano d’ingresso e comprende una prova gratuita; Scale ha una quota mensile più ampia e nessuna prova, perché ci si arriva passando da Studio. Prezzi e quote attuali sono sulla pagina Engine API.
Posso passare da Studio a Scale e viceversa?
Sì, una volta terminata la prova e andato a buon fine il primo pagamento, con il pulsante Passa a Scale (o Passa a Studio) nella scheda Chiavi API della tua dashboard. La nuova quota mensile si applica subito al tuo account. Un upgrade viene addebitato subito per il resto del periodo di fatturazione; un downgrade non viene rimborsato e il prezzo più basso si applica dal prossimo rinnovo.
Posso provare l'API prima di pagare?
Sì, in due modi. Nel riferimento API i pulsanti Esegui questo esempio usano una chiave demo pubblica, senza alcun account — solo lavori piccoli. E qualsiasi account CutOptim con accesso effettuato può creare chiavi di test dalla dashboard: hanno una propria piccola quota mensile, non vengono mai fatturate e non richiedono alcun abbonamento, così puoi costruire tutta l’integrazione prima di acquistare. Poi Studio parte con una prova gratuita.
Verrò avvisato prima che la mia quota mensile si esaurisca?
Sì. Inviamo un’email all’account al 90% della quota mensile e di nuovo quando è esaurita. Dopo di che le chiamate restituiscono 402 fino al ripristino della quota il primo giorno del mese successivo — oppure subito, se passi al piano più ampio.
Mi serve l'Engine API?
Quasi certamente no. Se tagli pannelli o barre aprendo CutOptim nel browser, l'app fa già tutto quello che fa l'API — l'API è lo stesso motore senza uno schermo attaccato. Esiste per una sola situazione: un altro software ha bisogno di piani di taglio senza che una persona apra l'app. Se dalla tua parte nessuno sta scrivendo codice che si collega a CutOptim, puoi ignorarla.
A chi serve davvero l'Engine API?
A due tipi di cliente: chi usa già un software dentro cui il piano di taglio dovrebbe stare — un ERP, uno strumento di preventivazione o di inserimento ordini, il software della macchina stessa — e chi si sta facendo sviluppare un software del genere, da uno sviluppatore interno o da un'agenzia. In entrambi i casi il lavoro lo fa chi scrive quel software, non tu nell'interfaccia di CutOptim.
Come ottengo l'accesso all'Engine API?
Puoi abbonarti dalla pagina Engine API: prevede un periodo di prova e l’accesso arriva da solo sul tuo account. È la via più rapida. Se preferisci descrivere prima la tua integrazione, o ti serve un volume oltre il piano standard, scrivici. In entrambi i casi poi le chiavi live le crei tu nella scheda Chiavi API della tua dashboard. L’Engine API è fatturata separatamente dai piani dell’app e nessun passaggio di piano la attiva.
L'Engine API taglia anche il legno o solo pannelli e barre?
Tutte e quattro le modalità dell’app: pannelli, barre, legno e nesting true-shape. L’endpoint del legno conosce la sezione: pezzi e materiale portano entrambi i lati della sezione, così un pezzo 50×150 viene tagliato solo da materiale 50×150. Il lavoro è diviso per sezione e ogni sezione torna con le proprie barre e i propri totali; la domanda la cui sezione non ha alcun materiale è segnalata separatamente dai pezzi che avevano materiale e non sono entrati.
L'Engine API cambia il mio piano Gratuito, Pro o Officina?
No. L'Engine API è un componente aggiuntivo separato e non cambia nulla dei normali piani. L'ottimizzatore dentro l'app è invariato, gira ancora nel tuo browser ed è ancora incluso in Gratuito, Pro e Officina esattamente come prima. Niente di ciò che fai nell'app inizia a consumare richieste API.
Esiste un SDK o una libreria client per l'Engine API?
Sì. Esistono SDK ufficiali open source per TypeScript (npm @cutoptim/engine), Python (PyPI cutoptim) e PHP (Composer cutoptim/engine) — codice su github.com/cutoptim, guida su /engine/reference/guides/sdks. Sono facoltativi: l'API resta semplice HTTPS con JSON, che ogni linguaggio può chiamare senza un pacchetto CutOptim. Per i job asincroni ci sono i webhook: registrate un endpoint nella dashboard e ricevete un POST firmato quando un job max termina, invece di interrogare. La maggior parte delle chiamate riceve direttamente il risultato finito; l'unica eccezione è il motore asincrono max — per i pannelli 2D e per il nesting a forma reale — dove POST /v1/optimize/2d o /v1/optimize/nest con engine "max" restituisce un id di lavoro che interroghi con GET /v1/jobs/{id} finché il risultato non è pronto.
Il motore balanced è migliore di quello predefinito?
No — è un compromesso, non un miglioramento. Il motore predefinito heuristic dà la resa più alta e ogni schema che produce è tagliabile su una sezionatrice, quindi restituisce sempre un piano di taglio. Il motore balanced è molto più rapido sui lavori molto grandi ma rende leggermente meno, e i suoi schemi spesso non sono tagliabili da bordo a bordo, quindi per quelli non restituisce alcun piano di taglio. Usalo solo quando la velocità su un lavoro grande conta più di un piano pronto per la sega.
Perché la mia chiave API viene mostrata una sola volta?
Perché CutOptim non conserva mai la chiave in sé — solo un hash sha256. Questo significa che nessuno, noi compresi, può rileggere la tua chiave dal database, quindi può essere mostrata soltanto nel momento in cui viene creata. Copiala subito nella configurazione del tuo software; se la perdi, elimina la chiave e creane una nuova.
Che cosa succede se revoco una chiave API — mi vengono restituiti dei soldi?
No, e non disdice nemmeno nulla. La revoca blocca quella singola chiave dalla chiamata successiva; l’abbonamento continua e la quota mensile resta. Revoca una chiave quando è stata esposta o un’integrazione viene dismessa, poi creane una sostitutiva. Per smettere di pagare disdici invece l’abbonamento: l’accesso prosegue fino alla fine del periodo già pagato e dopo smettono di funzionare anche le chiavi esistenti.
Creare più chiavi API mi dà più richieste?
No. La quota mensile appartiene all’account e ogni chiave attiva attinge allo stesso monte: una seconda chiave non aggiunge una seconda quota. Le chiavi servono a separare staging e produzione, dare a ogni integrazione la propria credenziale e revocarne una senza disturbare le altre. Esaurito il monte, ogni chiave restituisce 402, non solo quella che l’ha speso. GET /v1/usage riporta la posizione dell’account, con qualunque chiave tu chieda.
L'Engine API può restituire un disegno, non solo coordinate?
Sì. Aggiungi include: ["svg","csv","dxf"] a una richiesta di ottimizzazione e la risposta trasporta lo schema come file già pronto, inline nel JSON: un disegno SVG 2D autonomo, un DXF R12/AC1009 sui layer STOCK/PARTS/LABELS o una distinta di taglio CSV. Non c'è archiviazione né una seconda chiamata. L'SVG è solo 2D; una richiesta 1D o wood restituisce invece un avviso. Puoi anche allegare un oggetto meta (il codice articolo del tuo ERP, l'id della riga d'ordine o il riferimento cliente) a qualsiasi pezzo o riga di materiale, e torna invariato nell'output, così il piano si riconcilia con il tuo sistema. È anche il campo da usare per rileggere quale pannello ha scelto l'ottimizzatore: metti il tuo codice in stock[].meta e ti torna su sheets[].meta, senza mai influire sul posizionamento. Non usare invece il campo material per identificare: material è una partizione rigida — un pezzo viene tagliato solo da righe di materiale con lo stesso valore material — quindi assegnarlo a ogni riga di materiale lasciando i pezzi senza tag fa tornare ogni pezzo come unmatched, con un risultato vuoto.
Posso verificare una richiesta senza spendere una delle mie chiamate mensili?
Sì. POST /v1/validate/2d, /v1/validate/1d, /v1/validate/wood o /v1/validate/nest prende lo stesso corpo dell'endpoint di ottimizzazione corrispondente e lo verifica senza risolverlo — gratis, senza chiave API e senza quota spesa. Una richiesta malformata torna come 400 che indica il campo esatto sbagliato, mentre una ben formata restituisce valid: true più avvisi di fattibilità (come un pezzo che non entra in alcun materiale). Usalo per validare i tuoi payload mentre costruisci l'integrazione, ancora prima di avere una chiave.
Che fine fa un file SVG o DXF che invio all'API?
Non ne resta nulla. Il file viaggia come corpo della richiesta, viene letto in memoria per ricavarne il contorno del pezzo e sparisce appena la risposta è scritta — nessuna copia su disco, nessuna copia in un database, nessuna voce di log che lo contenga, quindi nulla da cancellare dopo e nessun periodo di conservazione da chiedere. È la stessa assenza di stato che tiene il resto dell'API: non conserviamo i tuoi piani di taglio più a lungo della richiesta che li ha prodotti.
Anche il nesting a forma reale ha un motore max?
Sì. POST /v1/optimize/nest con engine "max" è asincrono come il max 2D: la chiamata risponde 202 con un id di lavoro e interroghi GET /v1/jobs/{id}. Esegue prima il passaggio istantaneo lbf, poi impiega un budget di tempo — 60 secondi per default, da 10 a 180 tramite options.timeBudgetMs — cercando uno schema con meno pannelli, riempiendo un pannello alla volta. Non restituisce mai più pannelli di quanti servirebbero con lbf; quando non ne trova, ottieni lo schema lbf e un avviso che lo segnala. Poiché la ricerca è limitata nel tempo, le sue risposte portano deterministic: false. Accetta più dimensioni di pannello per materiale e respectStock, e mantiene il proprio risultato solo quando classifica meglio del piano lbf (in base al prezzo con options.minimizeCost, altrimenti in base all'area del pannello). Un pannello poligonale o le zone di esclusione, che la sua ricerca non può modellare, vengono serviti dal passaggio lbf all'interno del lavoro con un avviso — mai rifiutati.
Perché i pezzi rettangolari del nesting tornavano inclinati o su un pannello in più?
Prima del 2026-09-28 poteva succedere: il motore di nesting lbf trova le posizioni per campionamento, quindi con la rotazione libera poteva ruotare un pezzo quasi rettangolare di una frazione di grado, e raramente trovava una griglia senza alcun gioco, come tre pezzi da 500 mm affiancati su un pannello da 1500 mm con spaziatura zero. Ora entrambi i motori di nesting provano anche i pezzi agli angoli retti che consentono, impacchettano i rettangoli d'ingombro dei pezzi con un algoritmo esatto per rettangoli e mantengono il piano che si classifica meglio; a parità vince il piano che riempie i pannelli in ordine, dal primo all'ultimo, poi quello con meno pezzi inclinati. Non devi modificare la tua richiesta. Se i tuoi pezzi non devono mai uscire dagli angoli retti, invia come prima allowedRotations: [0, 90, 180, 270].
Posso impostare la distanza dal bordo del pannello separatamente dalla spaziatura tra i pezzi?
Sì. options.minSeparation è la spaziatura tra i pezzi, e da sola si applica anche al bordo del pannello. Aggiungi options.edgeClearance per impostare il bordo separatamente — per esempio 5 tra i pezzi e 0 o 10 al bordo. Funziona su entrambi i motori di nesting, e se lo ometti il bordo mantiene minSeparation esattamente come prima. Richiede pannelli rettangolari (w e h): con un pannello poligonale, o con un valore che non lascia spazio su un pannello, la richiesta viene rifiutata con un 400 prima che una chiamata venga addebitata. Le zone di esclusione mantengono minSeparation, come i pezzi.
Come sceglie il nesting tra più dimensioni di pannello?
Quando un materiale ha due o più righe di materiale, il motore lbf le prova nel tuo ordine, ogni dimensione da sola e in ordine dalla più economica, e tiene la migliore — quindi la risposta non dipende più da quale riga elenchi per prima. Classifica in base al maggior numero di pezzi da tagliare assolutamente posizionati (pezzi contrassegnati con priority, che conta con options.respectStock), poi al maggior numero di pezzi posizionati, poi alla minore area totale dei pannelli; con options.minimizeCost classifica invece in base al prezzo totale (price, o cost quando una riga non ha un prezzo), a condizione che ogni riga di quel materiale ne abbia uno. Poi ogni pannello, a partire dal meno riempito, viene ri-annidato da solo sulle righe più economiche o più piccole e sostituito quando l'intero piano classifica meglio — così le dimensioni possono essere mescolate all'interno di un materiale: tipicamente due pannelli grandi e uno più piccolo per ultimo. Con options.respectStock nessuna riga viene usata più spesso della sua qty. La risposta indica da quale riga proviene ogni pannello (sheets[].stock) e totalizza i pannelli, il prezzo e la densità per riga (stockUsage). Il motore max applica la stessa classifica.
Posso contrassegnare i pezzi del nesting come da tagliare assolutamente?
Sì: parts[].priority: true. Conta quando il materiale disponibile è limitato (options.respectStock), perché allora non tutti i pezzi potrebbero entrare: i pezzi da tagliare assolutamente vengono posizionati per primi, così un pezzo qualsiasi non si aggiudica mai lo spazio sul pannello di cui ha bisogno un pezzo da tagliare assolutamente, e ogni confronto tra piani classifica in testa quello che ne mantiene di più. Entrambi i motori di nesting lo rispettano. Senza respectStock ogni pezzo che entra viene comunque posizionato, quindi il flag non cambia nulla. Un pezzo da tagliare assolutamente che non entra in alcun pannello torna comunque in unplaced. (Prima del 2026-09-22 il motore di nesting accettava questo campo ma non agiva di conseguenza.)
La risposta del nesting include la lunghezza di taglio?
Sì. Ogni pannello porta cutLength — la somma dei perimetri dei contorni esterni e dei fori dei pezzi collocati, nella tua unità di misura — e pierces, uno per ogni contorno chiuso (il contorno di ogni pezzo più uno per ogni foro); metrics totalizza entrambi per l'intero lavoro. È la lunghezza geometrica del contorno: il taglio a linea comune, gli ingressi e le uscite della lama e i micro-giunti non sono inclusi, perché li aggiunge il CAM della tua macchina — quindi è una base solida per il tempo macchina e i consumabili, non il percorso utensile finale.
Posso addebitare solo la parte di pannello che un nesting usa?
L'API ti dà i numeri; la regola di addebito resta tua. Ogni pannello porta usedWidth e usedHeight — il punto più lontano raggiunto da un pezzo collocato, misurato dall'angolo di origine del pannello, nella tua unità di misura — e usedArea, il loro prodotto; stockUsage[].usedArea lo totalizza per riga di materiale. Un taglio orizzontale è usedHeight × la larghezza del pannello, un taglio verticale usedWidth × l'altezza del pannello, un riquadro d'ingombro usedArea. Entrambi i motori di nesting compattano inoltre per default il pannello meno riempito di ogni materiale: i suoi pezzi vengono ri-annidati sullo stesso pannello con sottoinsiemi di rotazione tra quelli consentiti a ciascun pezzo (0/180, 0/90/180/270, un solo orientamento per ogni copia — mai un angolo nuovo), e viene mantenuto lo schema con l'area usata più piccola. Il numero di pannelli, il prezzo e i pezzi posizionati non cambiano mai. options.compact: false restituisce lo schema non compattato. Se addebiti una striscia invece del riquadro d'ingombro, imposta options.compactFor su "horizontal" (l'altezza usata più bassa, per una striscia sull'intera larghezza del pannello) o "vertical" (la larghezza usata più piccola, per una striscia sull'intera altezza del pannello); il valore predefinito "box" minimizza l'area usata. Quanto si riduce l'area usata dipende dai pezzi, quindi nessuna frazione di pannello può essere promessa in anticipo.
Quanto budget di tempo devo dare al motore max per il nesting?
Il lavoro termina circa uno o due secondi dopo il suo budget, più l'eventuale attesa in coda. Per un lavoro di qualche decina di pezzi, 15 secondi (options.timeBudgetMs: 15000) di solito bastano; il predefinito è 60 secondi e l'intervallo va da 10 a 180. Un budget maggiore dà alla ricerca più occasioni di risparmiare un pannello, ma nessun budget può promettere un numero preciso di pannelli — dipende dai pezzi e dalla spaziatura. Interroga GET /v1/jobs/{id} ogni due o tre secondi; interrogare non costa quota.
L'API può rispettare la direzione della venatura di un pezzo?
Sì. Su POST /v1/optimize/2d, dai a una riga di materiale grain: "w" o "h" — il lato del pannello lungo il quale corre la venatura — e a un pezzo grain: "w" o "h" — il lato del pezzo che deve correre lungo di essa. Ogni pezzo così impostato viene posizionato con la venatura lungo quella del suo pannello, ruotato di 90° quando serve (rotated: true), e rotatable viene allora ignorato per quel pezzo. Si possono mescolare righe di materiale la cui venatura corre in direzioni diverse. Con material contano solo i pannelli del materiale del pezzo. Ogni pannello restituito ripete la venatura della propria riga. Se nessuna riga di materiale ha una venatura, la venatura di un pezzo non ha effetto e warnings lo segnala. Tutti e tre i motori 2D la supportano (max con la sua solita riga di materiale unica).
L'API può tagliare frontali abbinati in modo che la venatura prosegua da un pezzo all'altro?
Sì, su POST /v1/optimize/2d. Dai un id alle righe dei pezzi e nominale in matchedSets — per un frontale di cassetto sopra due ante, un layout con dir rows e le linee [DF] e [DOOR, DOOR]. Il set viene tagliato affiancato da un unico pezzo di pannello, esattamente a un kerf di distanza, e la venatura del set decide la direzione di ogni membro. Ogni membro posizionato torna con matchedSet (l'id del set, l'istanza e la sua posizione), e la risposta aggiunge un riepilogo matchedSets i cui warnings dicono, per esempio, quando le misure non combaciano. I motori heuristic e balanced dispongono i set; il motore max rifiuta un matchedSets non vuoto con un 400 prima che una chiamata venga addebitata. Gli export pdf e labelsPdf disegnano i membri come pezzi ordinari, e la risposta lo segnala; csv, svg e dxf contrassegnano i set. Senza un array matchedSets non vuoto non cambia nulla, e parts[].id viene controllato solo sulle righe che un set nomina.
grainGroup è ancora supportato?
Sì. grainGroup è deprecato ma ancora accettato, e funziona esattamente come prima: i pezzi che condividono un gruppo restano su un unico pannello. Non li ha mai posizionati uno accanto all'altro, quindi non dà una venatura continua tra di loro — per i frontali la cui venatura deve proseguire, usa invece matchedSets. Il motore max rifiuta grainGroup, come ha sempre fatto.

Aggiornato: 13 ottobre 2026