Optimización de corte (nesting)

Tutorial paso a paso del módulo de nesting de Despiece: el solver que empaqueta tus piezas en tableros stock minimizando desperdicio, con ciclo de tiempo estimado, secuencia de corte tipo TSP y exports listos para la sierra (PDF), la CNC (DXF), etiquetas por tablero y piezas 2D para outsource. La experiencia está enmarcada como propuesta de taller (no optimizador industrial) y suma un flujo por módulo para mantener el orden de armado a través de los tableros. El modelo de ejemplo es CocinaV9.despiece.

Despiece arma el plan en dos fases: un solver multi-restart (packNestMulti) elige las mejores placas por grupo de espesor, y un pipeline post-proceso calcula secuencia de corte (TSP 2-opt), ciclo de tiempo calibrable y exports. Atajo: N para abrir/cerrar el panel.

Novedades 2026-08 (vs v1 del tutorial)

FeatureDónde
Diagrama cut-man (cut #s + leyenda + labels)Workbench + PDF nest
Optimizar por módulo (A1 flujo)Setup ▸ Optimizar para
Tablero auto (phantom) + banner colapsableSetup + banner sobre el workbench
Compra sugerida CSVToolbar ▸ Compra sugerida
Guardar phantom → stock (1-click)Banner expandido
Propuesta de taller (badge + chips de yield)Toolbar del workbench
Etiquetas por tablero (≥2 tableros prompt)Workbench ▸ Etiquetas
Piezas 2D (.zip DXF) por pieza netaExportar ▸ Piezas 2D (no desde nest)

01 Cargar el modelo y abrir el panel

Vista general con el botón de nesting en la topbar
01 Botón de nesting en la topbar. Grupo 5 (Cómputo): el cuarto icono desde la izquierda es nesting (N). Está deshabilitado hasta que hay un modelo cargado y al menos una pieza con espesor válido.

Al importar el STEP/IGES/BREP/glTF/GLB, la sidebar izquierda muestra el árbol jerárquico. Para arrancar el corte el atajo es N, que abre el panel modal full-screen (nest-root) en modo Setup.

La cámara vuelve a vista isométrica con Home; el zoom encaja con F.

02 Setup: stock + sierra

Modo Setup del panel de nesting
02 Modo Setup. Columna izquierda: tableros del taller (presets + retazos del inventario). Columna derecha: knobs de sierra (kerf, recorte, rotación, primer corte, Optimizar para). Botón Calcular.

El Setup tiene dos columnas. La columna izquierda carga el stock del taller y la derecha opera la sierra y los knobs del solver:

Si tu modelo no tiene treePath o tenés un solo módulo, la cola de módulos aparece vacía — Despiece cae al comportamiento clásico (optimizar para material/tiempo) y la fila Sin módulo se ignora.

El botón Calcular dispara packNestMulti y, cuando termina, transiciona al modo Workbench.

03 Calcular y entrar al workbench (propuesta de taller)

Workbench con diagrama grande, badge Propuesta y chips de yield
03 Workbench con diagrama grande + badge Propuesta de taller. Tres columnas: piezas + sin colocar (rail), diagrama por tablero (stage canvas con drag/snap/rotate), secuencia de corte 1…N (cuts panel). Toolbar arriba con chips de yield + flow chip + acciones.

Tras Calcular, el panel pasa al modo Workbench (.nwb-workbench). La toolbar lleva ahora un badge Propuesta de taller como recordatorio explícito: lo que ves es una propuesta revisable, no un optimizador industrial — podés mover piezas con drag, sacarlas a sin colocar o recalcular.

El stage es un <canvas> que renderiza cada tablero en milímetros con relación de aspecto real. Las piezas se colorean por espesor / material; las rayas diagonales marcan veta. Las bandas perimetrales marcan los cantos (rojo 0,45 mm, azul 2 mm, custom) y debajo de cada tablero va una leyenda con esos mismos valores.

Al terminar el cálculo, sale un toast Propuesta lista · mirá % desperdicio y piezas sin colocar.

Tres sub-paneles: Partes (izquierda, items programados + sin colocar), Diagrama (centro, canvas interactivo), Cortes (derecha, 1…N pasos numerados con sus cotas).

04 Anatomía del diagrama cut-man

Zoom a un tablero del workbench con cut #s + leyenda 0,45/2 mm
04 Diagrama cut-man. Rectángulos de piezas (color = espesor, rayas = veta), outline del tablero, bandas rojas 0,45 mm y azules 2 mm por pieza, badges #N con el número de secuencia de corte y leyenda 0,45 / 2 mm en la esquina inferior derecha del tablero.

Cada rectángulo dentro del tablero codifica la misma info que antes, pero el renderizador cut-man agrega tres elementos nuevos (src/nesting/render-cuts.ts, render-edge-legend.ts, render-labels.ts):

VisualSignificado
Espesor 18 mm (melamina MDP por defecto).
Espesor 15 mm (fondo / tapa de cajón).
Espesor 9 mm (MDF crudo / fondo económico).
rayas a 45°respectsGrain: 'h' | 'v' — la pieza no rota; bloquea reordenamientos.
bandas rojas / azulesCantos en cada lado (rojo 0,45 mm · azul 2 mm · custom).
borde discontinuo verdeRetazo útil: puede volver al inventario como offcut.
badges #NSecuencia de corte del paso N — mismo orden que la tabla del panel derecho.
leyenda 0,45 mm / 2 mmEsquina inferior derecha del tablero, swatches de las bandas.

Click en un rectángulo lo selecciona en el rail izquierdo y dispara setNestHighlightedCutIndex para iluminar el paso de secuencia correspondiente en el panel derecho.

El PDF del nest usa el mismo renderBoard con showCutNumbers: true y showEdgeLegend: true, así el diagrama que ves en pantalla es idéntico al que mandás al taller. Los labels tienen outline oscuro (strokeText con rgba(14,39,64,0.85)) para que se lean incluso sobre el ámbar saturado de MDP.

05 Algoritmo: guillotine + maxrects + multi-restart

Acordeón Avanzado del setup
05 Acordeón Avanzado. Algoritmo (auto / guillotine / maxrects), cantidad de restarts, presupuesto de tiempo en segundos, semilla inicial.

El solver tiene tres modos (src/nesting/types.ts:NestStrategyChoice):

ModoAlgoritmoCuándo
auto (default)corre 5 restarts con estrategias distintas + shuffle seeded. Conserva el mejor.Taller genérico / primera pasada. Recomendado.
maxrectspackMaxRects — heurística de máximo rectángulo libre (Best Short Side Fit).Cuando querés minimizar retazos rectangulares grandes (CNC).
guillotinepackGuillotine — cortes válidos para sierra escuadradora (cada corte va de borde a borde).Sierra de banco / escuadradora (el más rápido).

En modo auto, packNestMulti (src/nesting/multi-restart.ts) itera entre 5 sort strategies (byMaxSide, byArea, byPerimeter, byHeight, byAspectRatio) con un shuffle seeded (mulberry32). El criterio del mejor resultado depende ahora de Optimizar para:

El restarts (1–20, default 5) sube la chance de encontrar un layout mejor; el timeBudgetMs (1000–30000, default 5000) corta el loop aunque queden restarts pendientes. Seed 0 = random; cualquier otro valor fija la corrida para reproducirla.

// Opciones que ve la UI (src/nesting/types.ts)
DEFAULT_NEST_OPTIONS = {
  kerf:         3,       // mm de disco
  borderMargin:  0,       // recorte de fábrica
  allowRotate:   true,
  strategy:      'auto',
  restarts:      5,
  timeBudgetMs:  5000,
  seed:          0,
  firstCut:      'v',
  optimize:      'material',
  optimizeWeight: 0.5,
  cutSequence:   'guillotine-naive',
}

06 Cycle-time y secuencia de corte (TSP)

Panel de cortes con cycle time
06 Panel de cortes con cycle time. Secuencia numerada, duración estimada por corte, sumado por tablero y plan total.

Una vez que el solver devuelve placements, un pipeline post-proceso calcula:

  1. Cuts: por cada tablero, el código genera una lista de CutStep (H o V + posición + longitud). Los cortes son los bordes internos del layout.
  2. Cut sequence: el algoritmo elegido ordena los cortes. Tres opciones (src/nesting/cut-sequence-tsp.ts:CutSequenceAlgorithm):
    • guillotine-naive — sort por dirección (V primero) y luego por posición. Back-compat.
    • nearest-neighbor — greedy O(n²) partiendo de (0,0). Reduce aire vs guillotine-naive.
    • tsp-2opt — nearest-neighbor + swaps por pares que reduzcan path. El que mejor resultado da.
  3. Cycle time (src/nesting/cycle-time.ts): por corte, cut_time = cutLength / (feedRate × feedRateScale), más rapid_time = airBeforeMm / rapidFeed, más plunge en el primer corte, toolchange por cambio de herramienta (CNC), flip heurístico (CNC, cuando se cruza el eje Z), setup por tablero y board_chg entre tableros. Calibración final: final_time = raw × (1 + overheadPct / 100), y labor_cost = (final / 3600) × hourlyRate.

El cycle time total ajustado por multiplicador de proyecto vive en result.totalTimeSec (top-level del NestResult) y se muestra en el cuts panel derecho.

Multiplicador de obra: el cycle time del plan se multiplica por settings.projectMultiplier (clamp 1–99). Útil para cotizar un juego de cocina × 2 unidades — entrás dos veces la misma cantidad de piezas y el time final sale × 2 sin tocar el solver.
// Spec: docs/superpowers/specs/2026-07-18-cut-time-estimation.md
cut_time   = cutLength / (feedRate × feedRateScale)
rapid_time = airBeforeMm / rapidFeed
plunge     = first cut only      // panel saw
toolchange = per tool boundary        // CNC
flip       = heuristic (Z crossing)   // CNC
setup      = setupTimeSec per board
board_chg  = boardChangeTimeSec per board // after first
final_time = raw × (1 + overheadPct / 100)
labor_cost = (final_time / 3600) × hourlyRate

07 Optimizar por módulo (flujo A1)

Cola de módulos en el setup
07a Cola de módulos en el setup. Una fila por módulo (1-8), con rank, nombre, conteo de piezas y handles ↑/↓/×. La fila Sin módulo se renderiza sola, al final.

Cuando elegís Optimizar para: Por módulo, el solver agrupa las piezas por módulo de armado (parent directo del leaf en el treePath) y optimiza para que cada módulo quede lo más concentrado posible — menos tableros distintos por módulo, mejor secuencia para armar en taller. El setup muestra una cola de módulos debajo del listado de stock:

Los módulos se resuelven desde el treePath de cada BuiltPart (src/nesting/module-resolve.ts:modulesFromTreePaths). Si el modelo es plano (sin jerarquía) o no tiene módulos reconocibles, la cola aparece vacía y el sistema cae al comportamiento de Material / Tiempo sin penalizarte.

Flow chip en la toolbar

Toolbar con chips de yield + flow chip + Compra sugerida
07b Toolbar con chips de yield + flow chip. Tras correr con optimize = by_module, el flow chip flujo 3,3 · 11 mod aparece debajo de los chips de yield. Hover lista cada módulo con su span (T1, T2, T4…).

Tras correr con optimize = by_module, la toolbar muestra un chip extra: flujo X.X · N mod (avg de tableros distintos por módulo). Hover sobre el chip lista cada módulo con su span:

# Tooltip del flow chip (nesting.workbench.flow_line)
Bajo 01        → T1,T3  (span 2)
Alacena        → T2     (span 1)
Mueble heladera → T4,T5  (span 2)
…
Los moduleStats se preservan incluso cuando recalculás con optimize = material (commit dc5c923), así que el chip sigue mostrándose como referencia histórica.

08 Edit SOTA: drag, snap, rotate

El workbench expone un set de ediciones manuales SOTA (spec §Edit SOTA):

El undo del workbench es local (no toca History 3D); se compone con el history general sólo si lo engancha el panel.

09 Tablero auto (phantom) + compra sugerida

Cuando el modelo tiene espesores / materiales que no matchean con el stock cargado, el solver ya no tira error: genera tableros auto (phantom) del tamaño mínimo necesario para las piezas huérfanas (src/nesting/material-pack.ts:generatePhantomStock). Los phantoms vienen con phantom: true y un badge · phantom en la cabecera del tablero en el canvas. Nunca se persisten en despiece.stockboards ni en despiece-stock.

Banner colapsable

Banner phantom colapsado por defecto
09a Banner colapsado por defecto. Una sola línea con el resumen del phantom usado; click expande. No roba alto al canvas del workbench.
Banner phantom expandido
09b Banner expandido. Lista de phantoms (material · dims · cantidad), botón Guardar en mis tableros (1-click + material picker), checkbox También al inventario del taller.

Compra sugerida (CSV)

Toolbar con botón Compra sugerida visible
09c Compra sugerida en la toolbar. El botón aparece sólo cuando el solver usó phantoms. Click descarga compra-sugerida-{modelo}.csv.

Si el solver usó phantoms, en la toolbar aparece el botón Compra sugerida (exportNestSuggestedBoards). Click genera y descarga compra-sugerida-{modelo}.csv:

# compra-sugerida-{modelo}.csv (UTF-8 BOM + CRLF)
material,espesor_mm,largo_mm,ancho_mm,cantidad,origen
Sin material,18,2750,1830,5,tablero_auto
MDF crudo,15,1830,600,2,tablero_auto

Una fila por phantom único (dedupeado por material × espesor × dims × cantidad).

10 Exportar: PDF · CSV · DXF · Etiquetas · Piezas 2D

La toolbar del workbench tiene cinco botones de export, todos sobre el resultado actual (respetan la selección del diagrama):

BotónSalidaSpec / módulo
PDFPlan completo en PDF (diagrama grande por tablero + tabla de secuencia de cortes + cantos por pieza).src/export-nest-pdf/, src/ui/nesting-export.ts:exportNestPdf
CSVListado pieza-a-pieza: coords, rotada, canto, material, tablero origen. Listo para abrir en Excel/Opticut.src/export-nest-csv/, src/ui/nesting-export.ts:exportNestCsv
Compra sugeridaCSV de tableros auto generados (sólo cuando hubo phantoms).src/export/nest-suggested-boards.ts
DXF (.zip)Un .dxf por tablero, bundleados en nest-{modelo}.zip. Formato AutoCAD R14, capas BOARD, PIECE, CUT, LABEL, GRAIN.src/export-nest-dxf/, spec 2026-07-18-export-nest-dxf.md
EtiquetasPDF de etiquetas pieza-a-pieza (datos para pegarlas en el taller).src/ui/nesting-export-labels.ts
El DXF y el CSV usan partsForExport() / el result.boards actual: si moviste una pieza con drag (paso 8), la nueva posición se exporta, no la original del solver.

Etiquetas filtradas por tablero

Prompt Etiquetas por tablero
10a Prompt Etiquetas por tablero. Cuando hay ≥2 tableros, el botón Etiquetas muestra este prompt inline. Vacío = todos; número = un tablero específico.

Cuando el resultado tiene ≥2 tableros, el botón Etiquetas muestra el inline prompt Etiquetas por tablero:

# Etiquetas por tablero
Número de tablero a reimprimir (1, 2, 3, 4, 5). Vacío = todos. Actual: 1.
[Vacio = todos los tableros                  ]   [Cancelar] [Guardar]

Default vacío = exporta todas las etiquetas. Ingresás un número y sólo se exportan las piezas de ese tablero (filtrado por boardIndex vía export-labels/filter.ts:filterCutLabels).

Piezas 2D (.zip DXF) — desde el menú Exportar

Las Piezas 2D viven en Exportar ▸ Piezas 2D (no en la toolbar del nest). Es un export independiente del cálculo de nesting — útil para mandar a un outsource / CNC sin compartir el layout:

A diferencia del nest-{modelo}.zip, los DXF de piezas 2D no llevan trayectorias ni G-code — son geometría para cotización / nesting externo.

Tabla resumen del output

¿Qué querés?BotónSpec
Llevar el plan a la sierraPDF2026-07-18-cut-time-estimation.md
Abrir en OptiCut o ExcelCSV
Cargar en AutoCAD / CAM (un DXF por tablero)DXF (.zip)2026-07-18-export-nest-dxf.md
Pegar etiquetas en las piezas físicasEtiquetas39ffc31 (filtro por tablero)
Cotizar / mandar a hacer afuera (un DXF por pieza)Exportar ▸ Piezas 2D95f4ce5
Comprar los tableros auto detectadosCompra sugeridab4d6188

11 Ciclar semilla R y comparar

El atajo R, mientras el panel está abierto y no está computando, dispara triggerRegenerate que es runCompute(true) con un nuevo seed aleatorio. La historia de restarts vive en result.restartsHistory y el mejor seed se persiste en result.bestSeed (top-level del NestResult).

Comparando corrida tras corrida se ve el efecto del shuffle: una pieza "rara" puede bajar 2–4 % el desperdicio cuando cae en un casillero que el baseline dejaba vacío. En modo auto + 5 restarts, el panel normalmente te muestra el mejor de los 5 al terminar.

Tiempo de cómputo: subir restarts a 20 o timeBudgetMs a 30 s puede duplicar el tiempo de cálculo sin mejorar el resultado. Para CocinaV9 (40–60 piezas) los defaults funcionan bien; subí restarts solo si tenés > 200 piezas o mezclas thicknesses.

12 Atajos de teclado

Hoja de atajos (panel de Ayuda)
12 Hoja de atajos. Help (botón de la topbar o ?) abre la hoja completa.

Los más usados en el flujo de nesting:

AtajoAcción
NAbrir / cerrar panel de nesting (toggleNestingPanel).
EscCerrar el panel (si no está computando).
RRecalcular con semilla nueva — dentro del panel, solo si no hay computación en curso.
R (pieza seleccionada)Rotar la pieza seleccionada 90° (siempre que orientationsForGrain lo permita).
Click + dragMover pieza en el workbench (snap-to-kerf).
Click rectánguloSeleccionar pieza en el rail e iluminar corte en el cuts panel.
Doble click listaMover pieza seleccionada a Sin colocar.
F / HomeFit / Fit + iso del viewport 3D.

En Mac el modificador de sistema es ; en otros sistemas Ctrl.


Ver también