Bastidor: hoop y place
Una máquina de bordar no borda diseños sueltos: borda un bastidor. Un
archivo hoop monta uno o varios diseños (cada uno en su propio archivo
.hoop) en el área útil de un bastidor real, en milímetros, y se compila a
un solo archivo de máquina. Este capítulo describe la declaración hoop,
sus propiedades, la instrucción place con todos sus modificadores, el
sistema de coordenadas, cómo se ordena el bordado entre diseños, dónde queda
el origen de los archivos de máquina y qué se valida. place también puede
usarse dentro de una capa de un design, para usar un diseño como componente
de otro; ese uso se describe al final y en Módulos.
Forma general#
hoop_decl := "hoop" STRING "{" ( prop | place | for | if ) * "}"
place := "place" STRING ( "(" args ")" )? "at" expr ( IDENT ":" expr )*Un ejemplo completo, el archivo bastidor.hoop:
hoop "Dos parches" {
frame: Brother_200x200
fabric: Twill
margin: 10mm
place "parche.hoop" at (100mm, 60mm)
place "parche.hoop"(nombre: "LUIS", ancho: 70mm) at (100mm, 120mm) anchor: top_center
}con el componente parche.hoop en la misma carpeta:
// file: parche.hoop
param nombre = "ANA"
param ancho: Length = 50mm
design "Parche" { canvas: rect(size: (ancho, 20mm), radius: 4mm) }
thread fondo = #f2f2f2 "Fondo"
thread borde = #1f3a8a "Azul"
layer base { fill fondo { shape: canvas } }
layer texto { text borde { value: nombre, height: 8mm, at: canvas.center + (0mm, 3mm), align: center } }
layer marco { satin borde { border: canvas, width: 2mm } }$ hoop check bastidor.hoop
bastidor.hoop: ok — 2 designs, 2 threads, 6 objectsReglas del archivo:
- Un archivo tiene un solo
designo un solohoop(si no:E007 a file has a single design (or a single hoop)). - Un archivo
hoopno puede tenerlayer: las capas van en el archivo de cada diseño (E007 a hoop places designs with place; layers go in each design's file). - Dentro del bloque sólo van propiedades,
place,foreif. Una primitiva (fill,satin, …),seq,insideolayerdirectamente en elhoopesE000 a hoop only places designs (movefillinto a design file); dentro de unifofordelhoop,E007 a hoop only places designs (place, for); stitches go in a design. - Una propiedad repetida es
E007 duplicateframe``. - Los elementos pueden separarse con saltos de línea o con comas:
hoop "H" { frame: Brother_100x100, margin: 8mm, place "a.hoop" at (50mm, 50mm) }es válido. - El archivo puede tener además
import,thread,const,shapeyparam(sus nombres se pueden usar en las expresiones de losplace).
Propiedades del hoop#
| Propiedad | Tipo | Por defecto | Significado |
|---|---|---|---|
frame | bastidor del catálogo o custom(ancho, alto) | — (obligatoria) | Área útil del bastidor, en mm. |
fabric | Twill, Pique, Fleece, Cap, Stretch | la tela del primer diseño colocado | Tela; manda sobre la de cada diseño. |
margin | Length | 5mm | Distancia mínima de lo cosido al borde del área útil. |
origin | top_left, center | top_left | Desde dónde se miden los at de los place (ver Sistema de coordenadas). |
Cualquier otra clave es E007 a hoop has no … (frame, fabric, margin, origin).
frame#
El valor es un nombre del catálogo o custom(ancho, alto) con dos Length:
| Nombre | Área útil (mm) |
|---|---|
Brother_100x100 | 100 × 100 |
Brother_130x180 | 130 × 180 |
Brother_160x260 | 160 × 260 |
Brother_200x200 | 200 × 200 |
Brother_200x300 | 200 × 300 |
Tajima_150x150 | 150 × 150 |
Tajima_240x240 | 240 × 240 |
Tajima_360x360 | 360 × 360 |
Cap_130x60 | 130 × 60 |
hoop "Modificadores" {
frame: custom(200mm, 200mm)
place "parche.hoop" at (60mm, 40mm) anchor: top_left
place "parche.hoop" at (150mm, 100mm) rotate: 90deg
place "parche.hoop" at (100mm, 180mm) anchor: bottom_center scale: 120%
}- Un nombre que no está en el catálogo es
E002 unknown frame…(catalog: …). customcon otros argumentos esE001 custom(width, height) takes two Length; cualquier otra expresión,E001 frame: a catalog frame or custom(width, height).- Sin
frameesE007 the hoop is missing frame, en la línea delhoop. Con unframeinválido se informa sólo ese error: sin bastidor no se revisa el área útil de cadaplace.
fabric#
La tela del hoop manda: cada diseño colocado se compila con esa tela,
de modo que los parámetros que el diseño no escribe (densidades, subcapas,
compensación de tirón) se resuelven para ella. Si el hoop no declara
fabric, cada diseño usa la suya y la tela del resultado es la del primer
diseño colocado. Un valor fuera de la lista es E002 (con sugerencia si hay
un nombre parecido); un valor que no es un nombre, E001.
margin#
Una Length; otro tipo es E001 margin is Length, not …. A diferencia
del margin de un design (0 a 20 mm), el del hoop no tiene rango
verificado.
place#
place "archivo.hoop"( "(" nombre: valor, … ")" )? at <Point> ( anchor: … | rotate: … | scale: … )*Coloca el diseño de archivo.hoop en el bastidor. Partes:
| Parte | Tipo | Por defecto | Significado |
|---|---|---|---|
"archivo.hoop" | literal String | — | El archivo del diseño (ver rutas). |
(nombre: valor, …) | argumentos con nombre | — | Valores para los param del diseño (ver componentes). |
at | Point | — (obligatorio) | Dónde cae el ancla del diseño, en coordenadas del bastidor. |
anchor: | nombre de ancla | center | Qué punto de la caja del diseño cae en at. |
rotate: | Angle | 0deg | Giro del diseño entero. |
scale: | Ratio (> 0) | 100% | Escala del diseño entero. |
- La ruta es un literal entre comillas: no puede ser una expresión.
ates cualquier expresión que dé unPoint: un literal(x, y), un nombre,grid(…),canvas.center + (5mm, 0mm)… Otro tipo esE001 at takes a Point (x, y), not …. Sinat,E000 expectedat (x, y)``.- Los modificadores van después de
at, en cualquier orden, separados por espacios (no por comas) y en la misma instrucción. Cada uno esnombre: valor. Una clave desconocida esE007 place has no…(anchor, rotate, scale); no existemirror. Un modificador o un argumento repetido esE007 duplicate…``. anchoraceptacenter,top_left,top_center,top_right,center_left,center_right,bottom_left,bottom_centerybottom_right; otro nombre esE002(con sugerencia o con la lista). Los alias cortos de los miembros de forma (top,left…) no valen aquí.rotatecon otro tipo esE001rotateis Angle, not ….scaledebe ser unRatiomayor que cero:0%o un valor negativo (-50%) esE002scalemust be greater than 0%; otro tipo,E001scaleis Ratio, not …. Si achica un texto bajo el mínimo de su fuente,W004en elplace(ver Diagnósticos).- Los argumentos van con nombre:
place "x.hoop"("ANA") at …esE001 design arguments are named: place "x.hoop"(nombre: "ANA").
Cómo se transforma un diseño colocado#
Para cada place, en este orden:
- Se compila el archivo del diseño (con sus
import, susparamcon los argumentos dados y la tela delhoop), en sus propias coordenadas. - Se escala por
scaley se gira porrotatealrededor del origen del diseño, (0, 0). Como el eje y apunta hacia abajo, un ángulo positivo gira en sentido horario en la pantalla. El ángulo de las puntadas de un relleno gira con el diseño (unfilla 45° colocado conrotate: 90degse borda a 135°). Un texto girado se borda letra por letra: cada letra se convierte en sus columnas y éstas se giran (la fuente no se gira sola). Los gruposseqse conservan, también cuando un texto se divide en letras. - Se calcula la caja del diseño ya escalado y girado: si el diseño
declara
canvas, la caja alineada a los ejes del lienzo transformado (el anclatop_centeres la del parche, no la de lo que tiene dentro); si no, la caja de lo cosido. - Se traslada para que el punto
anchorde esa caja caiga enat.
El lienzo de cada diseño colocado, transformado igual, se entrega al editor
para dibujarlo (Compiled::canvases); no forma parte del bordado.
En el ejemplo de bastidor.hoop, el primer parche (50 × 20 mm, ancla
center) ocupa de (75, 50) a (125, 70) mm; el segundo, de 70 mm de ancho y
con ancla top_center en (100, 120), ocupa de (65, 120) a (135, 140) mm.
Sistema de coordenadas#
- Las coordenadas del bastidor están en milímetros, con (0, 0) en la esquina superior izquierda del área útil, x hacia la derecha e y hacia abajo (como la pantalla y la máquina).
- Con
origin: center, (0, 0) es el centro del área útil, como en la máquina:place "escudo.hoop" at (0mm, 0mm)lo pone al centro, yat (0mm, -30mm)30 mm más arriba. La y sigue hacia abajo. Lo demás (margen,E006) no cambia; los mensajes muestran la posición medida desde la esquina. - El área útil va de (0, 0) a (ancho, alto) del
frame; lo cosido debe quedar dentro de[margin, ancho − margin] × [margin, alto − margin]. - El centro del área útil, (ancho / 2, alto / 2), es el origen de los archivos de máquina (ver abajo).
for e if dentro de un hoop#
for e if funcionan como en las capas (ver Control), y su
cuerpo sólo puede contener place, for e if:
hoop "Plancha" {
frame: Tajima_360x360
margin: 10mm
for nombre, i in ["ANA", "LUIS", "SOFÍA", "TOMÁS"] {
if i mod 2 == 0 {
place "parche.hoop"(nombre: nombre) at grid(i, cols: 2, step: (70mm, 40mm), start: (60mm, 40mm))
} else {
place "parche.hoop"(nombre: nombre) at grid(i, cols: 2, step: (70mm, 40mm), start: (60mm, 40mm)) rotate: 180deg
}
}
}- Cada vuelta del
forproduce unplaceindependiente, con los valores de la variable (y del índice) en ese momento. Hasta 1000 vueltas (E002 … iterations: a loop goes up to 1000). - En un
ifse verifican las dos ramas (sus errores se informan, incluido elE006del ancla), pero sólo se colocan los diseños de la rama elegida:
// error E006
hoop "H" {
frame: Brother_100x100
if false {
place "cuadro.hoop" at (500mm, 50mm)
} else {
place "cuadro.hoop" at (50mm, 50mm)
}
}$ hoop check hoopskip.hoop
hoopskip.hoop:4:5: error E006: (500.0, 50.0) mm is outside the frame's sewing area minus its marginLa galería trae una plancha de doce parches de nombre con grid
(docs/lenguaje/galeria/plancha.hoop).
Un solo archivo de máquina#
Todos los diseños de un hoop se juntan en un único diseño:
- Objetos: los de cada
place, en el orden de losplace(y de las vueltas de losfor). Cada objeto recuerda la línea delplaceque lo trajo (para ir de la vista al código). - Hilos: se juntan por color (sin distinguir mayúsculas en el
hexadecimal): si dos diseños declaran el mismo color, queda el primer
threadencontrado, con su nombre, marca y código. - Orden de bordado: el motor optimiza el orden entre todos los
diseños (los objetos del mismo hilo juntos, para tener menos cambios de
hilo), respetando las capas de cada diseño y los bloques
seq, que se cosen seguidos y en su orden. Doce parches de tres colores son dos cambios de hilo, no treinta y cinco. - Tela: la del
hoopo, si no la declara, la del primer diseño.
Origen de los archivos de máquina#
En un hoop, el origen (0, 0) de los archivos de máquina es el centro del
área útil del bastidor (redondeado a 0.1 mm), no la esquina ni el centro
del diseño. Las máquinas de formato relativo (Tajima DST, Melco EXP, Singer
XXX) empiezan donde está la aguja, que el operador centra en el bastidor: así
cada diseño cae donde dice su at. JEF guarda las distancias reales desde
ese origen; PES guarda además el bastidor (en un hoop, PES v6 lo lleva en
su cabecera). Las vistas SVG y el resumen siguen en coordenadas del diseño.
Un design compilado solo (sin hoop) usa como origen el centro de su
propio bordado.
Validación#
| Código | Cuándo | Dónde se informa |
|---|---|---|
E006 | El punto at está fuera de [margin, ancho − margin] × [margin, alto − margin]. | En el place, al verificar. |
E006 | Lo cosido del diseño ya colocado se sale del área útil menos margin. | En el place, al montar. |
W006 | Dos diseños colocados se pisan más de 0.5 mm². | En el place posterior de los dos. |
E007 | El archivo no se puede leer, es un hoop, coloca su propio archivo (ciclo) o recibe un argumento que no es param. | En el place. |
E004 | El diseño no tiene nada que coser, o el hoop no coloca ningún diseño. | En el place (o en la línea del hoop). |
Área útil (E006)#
Hay dos revisiones. La primera, al verificar, mira sólo el punto at:
// error E006
hoop "H" {
frame: Brother_100x100
place "cuadro.hoop" at (98mm, 50mm)
}h_e006a.hoop:3:3: error E006: (98.0, 50.0) mm is outside the frame's sewing area minus its marginLa segunda, al montar, mide lo cosido del diseño ya transformado (no su
lienzo): los puntos de su geometría (el camino de un corrido, los rieles de
un satín, el contorno de un relleno, el contorno de las letras de un texto).
La caja de esos puntos debe quedar dentro del área útil menos margin, con
una tolerancia numérica de 10⁻⁶ mm (tocar el margen exacto es válido). Con el diseño cuadro.hoop:
// file: cuadro.hoop
design "Cuadro" { canvas: rect(size: (20mm, 20mm)) }
thread negro = #1c1616 "Negro"
layer a { fill negro { shape: canvas } }// error E006
hoop "H" {
frame: Brother_100x100
place "cuadro.hoop" at (12mm, 50mm)
}h_e006b.hoop:3:3: error E006: `cuadro.hoop` spans (2.0, 40.0)–(22.0, 60.0) mm, outside the sewing area minus its 5 mm margin (100 × 100 mm frame)Con at (15mm, 50mm) el cuadro va de 5 a 25 mm y verifica.
Diseños que se pisan (W006)#
Para cada par de diseños colocados se calcula el área común real de sus
huellas (lo que cubre cada objeto en la tela). Si supera 0.5 mm², se avisa en
el place del segundo:
hoop "H" {
frame: Brother_100x100
place "cuadro.hoop" at (40mm, 50mm)
place "cuadro.hoop" at (50mm, 50mm)
}h_w006.hoop:4:3: warning W006: `cuadro.hoop` overlaps `cuadro.hoop` by 200.0 mm²
h_w006.hoop: ok — 2 designs, 1 threads, 2 objectsEs una advertencia: el archivo compila (un aplique encima de un fondo puede ser intencional).
Diagnósticos de los diseños colocados#
Los errores y advertencias de cada diseño colocado se informan en la línea
de su place, con el archivo y la posición dentro de él (ver
Diagnósticos):
h_noparam.hoop:4:3: error E001: in `parche.hoop` 1:1: error: `nombre` is String but it was given LengthSi algún diseño tiene errores, el hoop no compila; los demás se siguen
revisando (se informan todos los errores juntos, y después las
advertencias).
Ciclos y archivos que no son diseños#
- Un
placecuyo archivo es unhoop:E007…is a hoop; place takes design files. - Un archivo inexistente:
E007 cannot read…: …(el detalle lo da el sistema de archivos o el editor). - Un diseño que se coloca a sí mismo, directa o indirectamente:
E007 place cycle: a.hoop → b.hoop → a.hoop, en elplacede más afuera (ver Módulos). - Un
hoopsin ningúnplaceque llegue a colocarse:E004 the hoop places no designs, en la línea delhoop.
place dentro de un design#
place también vale dentro de una capa (y de for, if e inside) de un
design, con la misma sintaxis y la misma transformación. Las coordenadas
de at son entonces las del diseño que coloca. Diferencias con el hoop:
- La tela del diseño que coloca manda sobre la del componente.
- Los objetos del componente se insertan en la capa, en el lugar del
place; sus hilos se suman (sin repetir colores) y susseqse conservan. - No hay revisión de área útil ni
W006: lo colocado queda sujeto alcanvas(ymargin) del diseño que coloca y a susinside. Si se sale, el mensaje nombra alplace:
// error E006
design "Polera" { canvas: rect(size: (60mm, 50mm)) }
layer todo {
place "parche.hoop" at (50mm, 18mm)
}componente_fuera.hoop:3:3: error E006: place overflows the canvas by 15.0 mm on the rightUn ejemplo que verifica (docs/lenguaje/galeria/polera.hoop es otro):
design "Polera" { canvas: rect(size: (80mm, 50mm)), fabric: Pique }
thread azul = #1f3a8a "Azul"
layer todo {
place "parche.hoop"(nombre: "SOL") at (40mm, 18mm) scale: 80%
text azul { value: "2026", height: 6mm, at: (40mm, 46mm), align: center }
}Dentro de una capa, place debe ir seguido de un literal de texto
(place "…").
Véase también#
- Módulos: rutas,
import,paramy componentes. - Diagnósticos: todos los códigos.
- Herramientas:
hoop buildy los archivos que escribe. - Catálogos: bastidores, telas y fuentes.