MFL — MuebleLab Furniture Language Lenguaje para definir muebles en texto legible
¿Qué es MFL?
MFL es un lenguaje de dominio específico (DSL) escrito en castellano que te permite describir un mueble completo en texto plano. El sistema lo compila automáticamente y muestra el resultado en el preview 2D.
En lugar de hacer clic en la interfaz para configurar cada opción, escribes algo como:
mueble armario
ancho = 800
alto = 720
fondo = 400
grosor = 18
tablero = blanco
trasera = fino
zocalo = 80
distribucion
columnas = 2
filas = 2
A1 = puerta
A2 = cajon
cantidad = 2
B1..B2 = abierto
Reglas de sintaxis
Indentación
La indentación determina la jerarquía. Usa 2 o 4 espacios por nivel. Los tabuladores se convierten automáticamente a 4 espacios.
distribucion debe estar indentado dentro
de mueble, no al mismo nivel. Si no está indentado, el
compilador lo ignora y no aparecerán columnas ni filas.
# ✅ Correcto — distribucion es hijo de mueble
mueble armario
ancho = 800
distribucion # ← 2 espacios de sangría
columnas = 3 # ← 4 espacios
# ❌ Incorrecto — distribucion al nivel raíz (se ignora)
mueble armario
ancho = 800
distribucion # ← sin sangría, es un nodo separado
Comentarios de línea
Todo lo que sigue a # en una línea es un comentario y se ignora.
mueble armario # nombre del mueble
ancho = 1200 # 1200mm de ancho
# este es un comentario de línea completa
Comentarios de bloque
Usa ### para abrir y cerrar un bloque de comentario
que puede abarcar varias líneas.
###
Este bloque está desactivado temporalmente.
mueble viejo
ancho = 600
###
mueble activo
ancho = 1200
Asignación con =
Las propiedades se asignan con =.
El espacio alrededor del = es opcional.
Operador de rango ..
A1..C4 define un rango de celdas desde A1 hasta C4 (inclusive).
Estructura básica
mfl 1.0 # opcional — cabecera de versión
variable ancho-col = 400 # opcional — variables reutilizables
mueble
# — dimensiones
ancho = 1200
alto = 800
fondo = 400
grosor = 18
# — materiales
tablero = blanco
frente = blanco
canto = fino
trasera = fino
# — estructura
zocalo = 80
retranqueo = 60
# — defaults de contenido (opcional)
puerta
bisagra = izquierda
# — distribución interior
distribucion
columnas = 3
filas = 2
A1 = puerta
...
# — montaje (fase futura)
montaje
defecto = minifix
Dimensiones
| Propiedad | Valores | Notas |
|---|---|---|
ancho | número mm | Ancho exterior total |
alto | número mm | Alto exterior total |
fondo | número mm | Fondo exterior total |
grosor | número mm | Grosor del tablero. Defecto: 18mm |
Materiales y acabados
tablero — material de la carcasa
| Valor | Descripción |
|---|---|
blanconegrogrisgrafitoaluminio | Colores lisos |
roblepinohayanogal | Veteados de madera |
tablero = roble 18mm | Puedes añadir el grosor en mm |
frente — material de puertas y cajones
Acepta los mismos valores que tablero, más:
tablero = roble # carcasa en roble
frente = blanco mate # puertas blanco mate
canto
| Valor | Descripción |
|---|---|
fino | Canto de melamina 0.4mm |
grueso | Canto ABS 2mm |
trasera
| Valor | Descripción |
|---|---|
fino | HDF 6mm |
tablero | Mismo grosor que la carcasa |
ranurar (o ranurado) | Trasera en ranura fresada |
Zócalo y retranqueos
Bloque homogéneo: zocalo H con altura inline +
propiedades de retranqueo anidadas.
| Propiedad | Valores | Descripción |
|---|---|---|
zocalo H | número mm / no | Altura del zócalo (inline). zocalo no lo desactiva. |
alto | número mm | Alternativa al inline (dentro del bloque) |
retranqueo / frontal | número mm | Retranqueo frontal (defecto: 60mm) |
lateral | número mm | Retranqueo en los laterales |
trasero | número mm | Retranqueo trasero |
# Sintaxis homogénea (recomendada)
zocalo 80
retranqueo = 60
lateral = 30
trasero = 0
# Inline corto si solo te interesa la altura
zocalo 80
# Sintaxis vieja (compatible)
zocalo = 80
retranqueo = 60
retranqueo-lateral = 30
Coronación
| Propiedad | Valores | Descripción |
|---|---|---|
coronacion H | número mm / no | Altura del remate superior (inline). |
alto | número mm | Alternativa al inline |
coronacion 60 # remate de 60mm
# o como bloque
coronacion
alto = 60
Patas y ruedas
Patas
Bloque homogéneo (sintaxis recomendada): patas con
cantidad inline opcional + propiedades anidadas alto,
grueso, retranqueo,
cantidad.
| Propiedad | Valores | Descripción |
|---|---|---|
patas N | número (cantidad) | Activa N patas. Sin valor: 4 por defecto. patas no las desactiva. |
alto | número mm | Altura de las patas |
grueso | número mm | Sección cuadrada |
cantidad | 4 / 5 / 6 | Alternativa al inline. 4=esquinas, 5=+centro, 6=+2 centrales |
retranqueo | número mm | Retranqueo desde el canto |
anclaje | tornillo / inserto / pegado | Tipo de fijación pata-mueble. Defecto: tornillo (4 por pata desde dentro). inserto = inserto roscado M6 + tornillo M6×40 con arandela (típico de patas tipo tarugo). pegado = sin tornillería (cola). |
# Sintaxis recomendada (homogénea)
patas 4
alto = 120
grueso = 40
retranqueo = 50
anclaje = tornillo # tornillo | inserto | pegado
# Patas tipo tarugo con inserto roscado
patas 4
alto = 150
grueso = 35
anclaje = inserto
# También válido — solo inline (cantidad sin props extra)
patas 4
# Sintaxis vieja (compatible)
patas = si
altura-patas = 120
grosor-patas = 40
cantidad-patas = 4
retranqueo-patas = 50
anclaje-patas = inserto
tornillo→ 4 tornillos aglomerado 4.5×40 por pata.inserto→ 1 inserto rosca M6 + 1 tornillo M6×40 + arandela por pata.pegado→ solo cola (no se contabiliza como herraje).
pegado en mueble grande
(cara frontal > 1 m²) por riesgo de despegue.
Ruedas
Mismo patrón que patas:
| Propiedad | Valores | Descripción |
|---|---|---|
ruedas N | 2 / 4 | Activa N ruedas (inline). ruedas no las desactiva. |
cantidad | 2 / 4 | Alternativa al inline (dentro del bloque) |
ruedas 4
# o como bloque
ruedas
cantidad = 4
Convención: infinitivos para evitar ambigüedad de género
Cuando un valor describe un acabado o un proceso aplicable a piezas de distinto género (puerta vs. cajón vs. trasera…), MFL acepta tanto las formas con concordancia de género como el infinitivo del verbo, que es siempre neutro y se considera la forma canónica:
| Concepto | Adjetivo (con género) | Infinitivo (canónico) |
|---|---|---|
| Frente solapado al hueco | solapada · solapado | solapar |
| Frente embutido en el hueco | embutida · embutido | embutir |
| Trasera con ranura fresada | ranurada · ranurado | ranurar |
Las tres formas se aceptan, pero al exportar MFL se prefiere el infinitivo.
Para puertas, cajones, falsos frentes, paneles ciegos, etc.: usa
estilo = embutir en lugar de embutida/embutido.
Consola REPL — lectura y expresiones
La consola MFL es una terminal flotante con dos modos:
modificación (líneas con = que cambian el mueble)
y lectura (líneas sin = que consultan el estado
o evalúan expresiones aritméticas).
- Abrir/cerrar: tecla ` (acento grave) en escritorio, o desde el menú Ver → ⌨ Consola.
- Ejecutar: Ctrl+Enter o el botón ▶ (también disponible para móvil/táctil).
- Multi-línea: el textarea acepta varias líneas; todas se ejecutan en orden al pulsar Ejecutar.
- Cerrar: Esc, la ` otra vez, o la X de la barra.
- Mover: arrastra por la barra superior. La posición se recuerda.
Consultas simples
| Sintaxis | Devuelve |
|---|---|
A1 | Resumen de la celda (tipo, propiedades). |
A1.bisagra | Valor de una propiedad concreta. |
A1.ancho / A1.alto | Dimensiones reales de la celda en el lienzo. |
mueble | Resumen del mueble (dimensiones, distribución, construcción, zonas). |
lateral-izq, techo, suelo, tapa, fondo, zocalo, coronacion | Descripción de la pieza estructural. |
<nombre-de-zona> | Datos de una zona definida con nombre = .... |
? | Lista de aliases definidos. |
?? | MFL exportado completo del mueble. |
Expresiones aritméticas
Cualquier línea con operadores + - * / o paréntesis se
evalúa como expresión. Las propiedades del mueble y sus piezas son
accesibles con notación de punto encadenada:
# Lectura de propiedades numéricas
mueble.ancho → 800
comoda.lateral_izq.ancho → 19
comoda.tapa.voladizo_frente → 30
comoda.fondo.ancho → 762 (calculado)
# Cualquier expresión aritmética
comoda.ancho - 2 * comoda.grosor → 762
(comoda.ancho - 2*19) / 3 → 254
A1.alto / 2 → 227.5
# Variables locales (prefijo _)
_libre = comoda.ancho - 2 * comoda.grosor → 762
_libre / 3 → 254
_columna = _libre / 3 → 254
_columna * 2 → 508
Objetos disponibles
Cada objeto tiene propiedades numéricas accesibles con obj.prop:
| Objeto | Propiedades |
|---|---|
mueble · <nombre del mueble> | ancho, alto, fondo, grosor, interior_ancho, interior_alto, interior_fondo |
lateral_izq · lateral_dcha | ancho, alto, fondo |
techo · suelo | ancho, alto, fondo |
tapa | ancho, alto, fondo, voladizo_izq, voladizo_dcha, voladizo_frente, voladizo_trasero |
fondo (trasera) | ancho, alto, grosor |
zocalo | alto, retranqueo |
armazon | poste, lateral, travesano, ranura |
A1, B2, … | ancho, alto, fondo |
Las variables _xxx persisten durante la sesión de la consola
y se borran al recargar la página. Las expresiones solo se evalúan
en la consola; el MFL fuente del mueble sigue siendo declarativo.
Crear un mueble nuevo desde la consola
Por defecto, cuando pegas o escribes un bloque mueble X en la
consola, los hijos se aplican al mueble actualmente activo
(la cabecera se descarta). Para añadir un mueble nuevo al
escenario sin tocar el actual, antepón el verbo añadir o
nuevo:
añadir mueble armario
ancho = 1200
alto = 2000
fondo = 400
posicion = 800, 0 # x,y mm desde el origen del escenario
distribucion
columnas = 2
filas = 1
A1 = puerta
A2 = puerta
añadir muebleynuevo muebleson sinónimos.- La línea
posicion = x, yes opcional. Sólo se indican x (lateral, mm) e y (altura desde el suelo, mm). No hay coordenada Z porque todos los muebles del escenario comparten el mismo plano de fondo (la cara trasera) — sus frentes salen hacia adelante según su propiofondo. - Convención Cartesiana: X crece hacia la derecha, Y
crece hacia arriba.
posicion = 0, 0deja el mueble apoyado en el suelo. Para apilar otro encima, su Y = altura del mueble que le soporta:añadir mueble base ancho = 800 alto = 720 fondo = 400 posicion = 0, 0 # apoya en el suelo añadir mueble vitrina ancho = 800 alto = 600 fondo = 350 posicion = 0, 720 # apoya sobre el mueble base (alto = 720 mm) - Si se omite
posicion, el mueble se coloca a la derecha del último. - El origen (0, 0) está dibujado abajo-izquierda del lienzo: eje rojo X→ y eje verde Y↑. Es el suelo en la pared izquierda de la composición.
- Los verbos
añadir/nuevoson exclusivos de la consola; no forman parte del MFL serializado en disco. El propio mueble nuevo, una vez añadido, se exporta como un bloquemueble Xnormal.
Piezas, uniones y hardware
El editor reconoce las piezas físicas que componen un mueble (laterales, techo, suelo, trasera, divisores internos, zócalo) y detecta automáticamente las uniones entre ellas. Para cada unión se asigna por defecto una tornillería estándar, que se puede sobrescribir desde la consola REPL. Las modificaciones se guardan en el modelo y afectan al despiece y al inventario de tornillería.
Identificadores de piezas
techo,suelo,lateral_izq,lateral_dcha,traseradivisor_h_1,divisor_h_2… (de arriba a abajo)divisor_v_1,divisor_v_2… (de izquierda a derecha)zocalo_frontal· si tiene zócalo
Consultas en la consola
A1.bordes
→ arriba: techo, abajo: divisor_h_1, izq: lateral_izq, dcha: divisor_v_1
techo.uniones
→ lateral_izq L-corner (eje x)
lateral_dcha L-corner (eje x)
trasera butt (eje y)
divisor_v_1 butt (eje y)
union(divisor_h_1, lateral_izq)
→ T-joint (eje x) · Tubillón 8×30 ×2 + Minifix M6×11 ×2
union(divisor_h_1, lateral_izq).hardware = allen×2
→ guardado: union(divisor_h_1, lateral_izq).hardware = allen×2 [override]
inventario
→ tubillón 8×30 ×18
minifix M6×11 ×10
allen ×2 ← el override aparece aquí
Tipos de unión detectados
| Tipo | Cuándo |
|---|---|
L-corner | Esquina del mueble (lateral con techo o suelo) |
T-joint | Divisor interno apoya en lateral o en otro divisor |
cross | Dos divisores se cruzan en el interior |
butt | Caso genérico (trasera, etc.) |
Tipos de tornillería disponibles
tubillón, minifix, allen,
escuadra, cabezal (escondido tipo Hettich),
tornillo (madera), grapa.
Sintaxis libre admite combinaciones:
tubillón×4 + minifix×2,
allen M6×30 ×2.
Operaciones CNC, validación y montaje
Las uniones generan automáticamente las operaciones de mecanizado (taladros, fresados) en cada pieza, con coordenadas, diámetros y profundidades. Si modificas una unión a otro tipo de hardware, las operaciones se recalculan al instante y se reflejan en el export al CNC.
lateral_izq.operaciones
→ 22 operaciones:
Tubillón 8×30 x= 50 Ø8×15 (lateral_izq↔techo)
Tubillón 8×30 x=150 Ø8×15 (lateral_izq↔techo)
Minifix · radial x= 50 Ø5×40 (lateral_izq↔techo)
Allen M6×30 pasante x= 50 Ø6×through (lateral_izq↔divisor_h_1)
...
cnc # resumen del export completo (mueble + piezas + ops + hardware)
validar # detecta uniones problemáticas
→ 1 aviso(s):
⚠ lateral_izq ↔ divisor_h_1: allen sin tubillón puede pivotar — añade alineadores
montaje # secuencia paso a paso
→ 1. Forma la caja exterior (lateral_izq, lateral_dcha, techo, suelo)
2. Coloca los divisores horizontales (divisor_h_1, divisor_h_2)
3. Coloca los divisores verticales (divisor_v_1)
4. Coloca la trasera
5. Atornilla el zócalo frontal
El comando cnc exporta una estructura JSON con todas las piezas,
sus operaciones y las uniones. Cualquier postprocesador específico de tu CNC
(Maestro, NestPlus, propietario) puede consumirlo y traducirlo a su formato.
Construcción (caja vs armazón)
MFL ofrece dos modos de construcción. Por defecto, el mueble se fabrica como
una caja de tablero (laterales gruesos pegados, suelo y techo).
Activando construccion = armazon, se construye con
4 postes verticales en las esquinas, paneles laterales finos
encastrados en ranuras y travesaños horizontales entre cajones —
tipo cómoda Shaker o vitrina inglesa.
| Propiedad | Valores | Descripción |
|---|---|---|
construccion | caja / armazon | Modo de fabricación (defecto: caja). En bloque: construccion armazon inline. |
poste | número mm | Sección cuadrada del poste (defecto: 35 mm) |
lateral | número mm | Grosor del panel lateral encastrado (defecto: 10 mm) |
travesano | número mm | Altura del travesaño horizontal (defecto: 30 mm) |
ranura | número mm | Profundidad de la ranura del panel (defecto: 8 mm) |
# Sintaxis homogénea recomendada
mueble comoda_pino
ancho = 800
alto = 900
fondo = 450
construccion armazon
poste = 40
lateral = 12
travesano = 35
patas 4
alto = 80 # los postes prolongan desde aquí
tapa
izq = 20
dcha = 20
frente = 30
distribucion
columnas = 1
filas = 4
A1..A4 = cajon
Las claves viejas con sufijo (armazon-poste, voladizo-izq,
altura-patas…) siguen funcionando, pero la sintaxis con bloque y
propiedades anidadas es más legible y se prefiere en MFL exportado.
En modo armazón los postes son las patas (no hay pieza separada), los laterales gruesos se sustituyen por paneles finos encastrados, y la trasera se encastra en ranura interior de los postes traseros.
Paneles opcionales
Permite omitir paneles de la carcasa para crear muebles abiertos o de esquina.
| Propiedad | Efecto |
|---|---|
sin-lateral-izq = si | Omite el panel lateral izquierdo |
sin-lateral-dcha = si | Omite el panel lateral derecho |
sin-techo = si | Omite el tablero superior |
sin-suelo = si | Omite el tablero inferior |
Cornisa decorativa
Moldura de remate sobre la tapa, decorativa. Típica en vitrinas y muebles rústicos. Sobresale por delante y los laterales con un perfil específico. Se vende por metros lineales en tiendas de bricolaje (Leroy Merlin, Bricomart, Maderas locales, Amazon) — el despiece la cuenta así.
| Propiedad | Valores | Descripción |
|---|---|---|
cornisa H | número mm o (bloque) | Activa cornisa. Inline = altura. cornisa no desactiva. |
alto | número mm | Altura de la moldura (defecto: 35 si no inline) |
perfil | escalonrectoredondocurvocoronagola | Forma de la sección de la moldura |
voladizo | número mm | Saliente respecto al cuerpo del mueble (defecto: 8) |
# Vitrina rústica con cornisa de roble en escalón
mueble vitrina_roble
ancho = 1200
alto = 1400
fondo = 380
tablero = pino
cornisa
alto = 35
perfil = escalon
voladizo = 10
# Forma corta — solo altura
cornisa 30
ancho + 2·voladizo;
los laterales (cuando aplica) miden fondo − T. Hardware: clavillos
pin de 1mm cada ~150mm + 3–5 tornillos ocultos desde dentro, y cola
blanca para las uniones a inglete (45°).
Marco frontal (face frame)
Para muebles tipo vitrina, alacena o cualquier construcción donde quieres un tablero superior visible y holguras entre las puertas y los laterales. Útil cuando las puertas son de cristal, tienen tirador exterior, o simplemente para evitar que se rocen al abrir.
Al activar marco todas las puertas se fuerzan a
estilo = encastrada automáticamente — no tiene
sentido superpuesta con marco visible.
| Propiedad | Valores | Descripción |
|---|---|---|
marco H | número mm o (bloque) o no | Activa marco. Inline = altura del tablero superior. marco no desactiva. |
superior / tablero-superior | número mm | Alto del tablero superior del marco |
entre | número mm | Separación entre puertas |
lateral | número mm | Separación entre puerta y lateral del mueble |
# Vitrina con marco frontal y 3 puertas de cristal
mueble vitrina
ancho = 1200
alto = 1400
fondo = 380
tablero = pino
marco
superior = 80 # tablero superior 80mm de alto
entre = 4 # 4mm de separación entre puertas
lateral = 4 # 4mm de separación con los laterales
distribucion
columnas = 3
filas = 1
A1 = puerta
A1.cristal = si
B1 = puerta
B1.cristal = si
C1 = puerta
C1.cristal = si
# Forma corta: solo tablero superior
marco 60
Largueros traseros
Cuando un mueble no lleva fondo completo (típico bajo cocina con paso de tubos, mueble pared abierto, etc.) los largueros traseros le dan estabilidad estructural sin cerrar la parte de atrás. Pueden ir arriba, abajo o ambos.
| Propiedad | Valores | Descripción |
|---|---|---|
largueros | (bloque) | Activa ambos por defecto. Sus props anidadas afinan. |
superior | si / no | Larguero superior trasero (dentro de bloque) |
inferior | si / no | Larguero inferior trasero (dentro de bloque) |
alto | número mm | Altura del larguero (defecto: 80 mm) |
grueso | número mm | Grosor — defecto: igual al tablero de carcasa |
# Bajo de cocina sin fondo, con largueros arriba y abajo
mueble cocina_fregadero
ancho = 800
alto = 720
fondo = 580
trasera = no
largueros
superior = si
inferior = si
alto = 80
distribucion.columnas = 1
distribucion.A1 = puerta
# Solo larguero superior (mueble pared abierto)
largueros
superior = si
inferior = no
# Sintaxis suelta (compatible)
larguero-superior = si
larguero-inferior = si
altura-larguero = 80
ancho-interior × alto × grosor.
Doble cara (espalda contra espalda)
Mueble pensado para verse y usarse por las dos caras: isla de cocina, separador de salón, biblioteca de doble cara, mostrador de oficina, etc. Construcción real: dos carcasas de tablero pegadas espalda contra espalda con sus dos fondos de 3 mm. Cada cara se diseña independientemente; la rejilla estructural (columnas y filas) es común a ambas caras — los divisores verticales y horizontales atraviesan todo el fondo del mueble.
Activación
| Propiedad | Valores | Descripción |
|---|---|---|
doble-cara | si / no | Activa el modo doble cara (default: no) |
anclaje | suelo / pared / techo / ninguno | Indica si el mueble va anclado a una superficie (afecta a refuerzos automáticos y warnings de estabilidad) |
Bloque dorso
Dentro de distribucion, un sub-bloque
dorso contiene las asignaciones de celdas de la
cara trasera. Si no se declara, la cara trasera queda como panel ciego.
mueble separador_salon
ancho = 1800
alto = 1700
fondo = 600
doble-cara = si
anclaje = suelo
distribucion
columnas = 3 A:600 B:600 C:resto
filas = 2 1:1000 2:resto
# Cara FRENTE
A1 = puerta
B1 = puerta
C1 = puerta
A2 = cajon
cantidad = 2
B2 = cajon
cantidad = 2
# Cara DORSO (sub-bloque)
dorso
A1..B1 = abierto
A2..B2 = abierto
C1 = puerta
Celdas pasantes
Una celda marcada pasante = si es un hueco que
atraviesa ambas caras sin fondo medianero: ves de un
lado a otro y la profundidad utilizable es el fondo total del mueble.
El compiler sincroniza ambas caras a abierto
automáticamente. Incompatible con puerta o
cajon en cualquiera de las dos caras.
distribucion
columnas = 3
filas = 1
A1 = puerta
B1 = abierto
B1.pasante = si # B1 queda pasante en ambas caras
C1 = puerta
Reglas constructivas automáticas
Al activar doble-cara = si, el compiler inyecta
refuerzos automáticamente para garantizar rigidez estructural y emite
warnings cuando las dimensiones cruzan umbrales críticos. No necesitas
declararlos manualmente:
| Regla | Acción / Aviso |
|---|---|
| Default | Larguero superior + inferior activados (hasTopRail/hasBottomRail) |
Con encimera = si | Se omite el larguero superior (la encimera maciza ya cose el conjunto) |
Con anclaje = suelo | Se omite el larguero inferior (el anclaje al suelo ya estabiliza) |
Con anclaje = techo | Se omite el larguero superior |
alto > 1400 sin encimera/anclaje | Warning: “añade larguero intermedio o anclaje exterior” |
alto > 1800 sin encimera/anclaje | Warning de vuelco crítico |
fondo > 600 | Aviso: costados largos pueden pandear, considera refuerzo a media profundidad |
fondo > 700 | Aviso: añadir hilera central de apoyos bajo la junta de fondos |
ancho > 1600 + pocas patas | Sugerencia: añadir apoyos cada ~80 cm |
ratio alto/fondo > 5 | Aviso de esbeltez: considera anclaje si cargas peso por una cara |
Profundidad útil de cajones en doble cara
Como cada cara tiene su propia mitad del fondo, los cajones que vivan en una cara solo pueden ocupar esa mitad (no son pasantes). La regla:
# cajón.profundidad ≤ (fondo_total − 2×grosor_fondo − holgura) / 2
#
# Para fondo_total = 600 mm: cajón.z máximo ≈ 290 mm
# Para fondo_total = 400 mm: cajón.z máximo ≈ 190 mm
# Para fondo_total = 320 mm: cajón.z máximo ≈ 150 mm (mínimo viable)
Si el fondo total es menor de 320 mm el compiler emite un warning diciendo que la mitad útil no es suficiente para un cajón estándar.
UI
En el editor visual (app.php), al activar “Doble cara” en
propiedades del mueble aparecen tabs Frente/Dorso
encima del lienzo 2D, con un thumbnail de la otra cara
en la esquina inferior derecha. Clic en el thumbnail intercambia la
cara activa. El visor 3D refleja la cara activa; cambia con los tabs.
mfl/ejemplos/09-separador-doble-cara.mfl
o ejecutar npm test para revisar la suite de pruebas
(“Doble cara”) en mfl/tests/compiler.test.js.
Tapa y encimera
Tapa
Tablero decorativo encima del mueble, del mismo material que la carcasa.
Bloque homogéneo: tapa + voladizos por lado.
| Propiedad | Valores |
|---|---|
tapa / tapa no | Activa o desactiva la tapa |
izq / izquierda | número mm — vuelo lateral izquierdo |
dcha / derecha | número mm — vuelo lateral derecho |
frente | número mm — vuelo frontal |
trasero | número mm — vuelo trasero |
# Sintaxis homogénea
tapa
izq = 20
dcha = 20
frente = 30
# Sintaxis vieja (compatible)
tapa = si
voladizo-izq = 20
voladizo-frente = 30
Encimera
Superficie de piedra, compacto u otro material sobre el mueble.
| Propiedad | Valores |
|---|---|
encimera | si / no |
Bloque distribución
El bloque distribucion define cómo se divide el interior
del mueble en columnas, filas y celdas.
Debe ir indentado dentro de mueble.
mueble armario
...
distribucion
columnas = 3 A:400 B:400 C:resto
filas = 2 1:560 2:resto
A1 = puerta
A2 = cajon
B1 = puerta
B2 = abierto
C1..C2 = abierto
Columnas y filas
columnas
Define el número de columnas y, opcionalmente, el ancho de cada una. Las columnas se identifican con letras: A, B, C…
columnas = 3 # 3 columnas de igual ancho
columnas = 3 A:400 B:400 C:resto # A y B fijas, C ocupa el resto
columnas = 2 A:300 B:500 # anchos explícitos sin 'resto'
filas
Define el número de filas y, opcionalmente, el alto de cada una. Las filas se identifican con números: 1, 2, 3… (de arriba a abajo).
filas = 4 # 4 filas de igual alto
filas = 2 1:560 2:resto # fila 1 de 560mm, fila 2 ocupa el resto
filas = 3 1:200 2:200 3:resto
resto (o fill) indica que esa columna
o fila ocupa todo el espacio que no han tomado las de tamaño fijo.
Si hay varias con resto, se reparten el espacio restante a partes iguales.
Asignación de celdas
Cada celda se identifica por su columna (letra) y fila (número): A1,
B2, C3…
A1 = puerta # celda A1 → puerta
B2 = cajon # celda B2 → cajón
C1 = abierto # celda C1 → espacio libre
Las celdas no asignadas quedan como abierto por defecto.
Dividir una celda en partes
Para subdividir solo una columna (o solo una fila) sin afectar
al resto, usa dividir-horizontal o
dividir-vertical. El compilador expande el grid
automáticamente y mantiene las demás columnas como una sola pieza alta.
distribucion
columnas = 3
filas = 1
A1 = puerta
B1 = abierto
B1.dividir-horizontal = 3
C1 = puerta
| Propiedad | Valor | Efecto |
|---|---|---|
dividir-horizontal | número > 1 | Divide la celda en N filas internas. El resto de columnas se extienden con rowSpan = N. |
dividir-vertical | número > 1 | Divide la celda en N columnas internas. El resto de filas se extienden con colSpan = N. |
filas = N globalmente y usar
rangos (A1..A3 = puerta) en las columnas no divididas, pero más
corto e intuitivo.
Bisagras automáticas
El compilador asigna bisagras solo, sin que tengas que escribirlas:
- Primera columna con puerta →
bisagra = izquierda(sobre el lateral izq). - Última columna con puerta →
bisagra = derecha(sobre el lateral der). - Columnas intermedias → encadenan con la vecina izquierda (evita colisiones al abrir).
Solo escribe .bisagra = ... si quieres romper la regla
automática. Si dos puertas adyacentes acaban con bisagras enfrentadas
(derecha seguida de izquierda),
el compilador emite un aviso porque chocarían al abrirse.
Dot paths — sintaxis sin indentar bloques
Cualquier propiedad anidada se puede escribir con notación
bloque.propiedad = valor, sin tener que indentar el bloque.
Las dos formas son equivalentes y mezclables.
# Indentado (forma clásica)
mueble armario
distribucion
columnas = 3
filas = 1
A1 = puerta
A1.bisagra = derecha
puerta
tirador = pomo
# Dot path (forma compacta)
mueble armario
distribucion.columnas = 3
distribucion.filas = 1
distribucion.A1 = puerta
distribucion.A1.bisagra = derecha
puerta.tirador = pomo
Prefijos soportados: distribucion,
puerta, cajon,
balda, barra,
carpinteria.
Rangos y excepciones
Rangos de celdas (..)
Asigna el mismo contenido a un bloque rectangular de celdas.
A1..A3 = balda # toda la columna A: 3 baldas
B1..C2 = puerta # columnas B y C, filas 1 y 2: puertas
A1..C4 = abierto # toda la distribución: todo abierto
Excepciones puntuales (celda.propiedad)
Cambia una propiedad de una celda concreta sin alterar su tipo.
A1..A2 = puerta # ambas son puertas con bisagra izquierda
A2.bisagra = derecha # solo A2 cambia la bisagra
Propiedades de subcelda (sub-indentadas)
Puedes añadir propiedades a una celda concreta indentándolas debajo de su asignación.
B2 = cajon
cantidad = 3 # esta celda tendrá 3 cajones
cierre-suave = si
Propiedad por rango (rango.propiedad)
Aplica una propiedad a todas las celdas de un rango de una sola vez. Útil cuando varias celdas comparten el mismo ajuste.
A1..A3 = puerta # toda la columna A son puertas
A1..A3.bisagra = derecha # las tres con bisagra a la derecha
Alias de rangos (nombre = a1..a3)
Pon nombre a un rango para reutilizarlo en cualquier punto del mueble.
Ahorra repetir direcciones cuando aplicas varias propiedades a las mismas
celdas, y permite referenciar el mismo rango desde distribucion
y desde zona.
mueble armario
ancho = 1500
alto = 2000
fondo = 580
primera_columna = a1..a3 # declaración GLOBAL (a nivel mueble)
fila_top = a1..c1
distribucion
columnas = 3
filas = 3
primera_columna = puerta # A1, A2, A3 son puertas
primera_columna.bisagra = derecha # las tres con bisagra a la derecha
fila_top = balda # A1, B1, C1 son baldas
zona primera_columna puerta # zona usa el mismo alias
bisagra = izquierda
- El identificador admite minúsculas, dígitos,
_y-. No puede ser una dirección de celda (A1) ni una palabra reservada (ancho,columnas, etc.). - El valor declarado es una celda (
a1) o un rango (a1..a3). - Ámbito: las declaraciones a nivel mueble (hijas directas de
mueble) son visibles desdedistribucionyzona. También se admiten declaraciones dentro dedistribucion, con ámbito limitado a ese bloque. - Usos válidos: asignación de contenido (
primera_columna = puerta), propiedad por rango (primera_columna.bisagra = derecha) y rango de zona (zona primera_columna puerta). - Si un alias no se ha declarado, la línea se ignora silenciosamente — no aborta la compilación.
Tipos de contenido
| Tipo | Descripción |
|---|---|
puerta | Puerta batiente |
cajon | Cajón o bloque de cajones |
balda | Balda fija o regulable |
barra | Barra de colgar ropa |
abierto | Espacio libre sin elemento (defecto) |
falso-frente | Panel decorativo sin función |
ciego | Panel tapón sin bisagra ni tirador |
Puerta
| Propiedad | Valores | Descripción |
|---|---|---|
bisagra |
izquierdaderechaarribaabajo |
Lado de la bisagra. Defecto: izquierda |
hojas | 1 / 2 | Puerta de dos hojas |
estilo |
superpuestaencastradainterior |
superpuesta (overlay): cubre la cara frontal del mueble (típica IKEA, defecto). encastrada (inset/flush): a ras de la cara frontal, con reveals visibles. interior: retranqueada hacia adentro del mueble. También acepta sinónimos: solapar/solapada (= superpuesta), embutir/embutida (= encastrada).
|
cristal | si / no | Puerta con cristal |
espejo | si / no | Puerta con espejo |
cierre-suave | si / no | Amortiguador de cierre |
kit | si / no | Puerta comprada hecha — no se fabrica nada en taller. Las bisagras se siguen contando |
tirador | ver sección tiradores |
A1 = puerta
bisagra = derecha
hojas = 2
cristal = si
# Puerta de catálogo (IKEA, etc.) — solo necesita bisagras
B1 = puerta
kit = si
Cajón
| Propiedad | Valores | Descripción |
|---|---|---|
cantidad | número | Número de cajones en el bloque |
separacion | número mm | Separación entre frentes (defecto: 2mm) |
estilo |
superpuestoencastrado |
Frente del cajón superpuesto (sobresale) o encastrado (a ras). Sinónimos: solapado/embutido. |
espejo | si / no | Frente del cajón con espejo |
cierre-suave | si / no | Guías con amortiguador |
push | si / no | Apertura por presión, sin tirador |
kit | si / no | Cuerpo del cajón comprado (laterales, fondo, base, correderas) — solo se fabrica el frontal de madera |
tirador | ver sección tiradores |
B2 = cajon
cantidad = 3
cierre-suave = si
tirador = barra
# Kit Blum / Hettich / GTV: cuerpo viene comprado, frontal a medida
A1 = cajon
kit = si
Balda
| Propiedad | Valores | Descripción |
|---|---|---|
cantidad | número | Número de baldas (divide la celda horizontalmente) |
regulable | si / no | Sistema 32mm |
C1 = balda
cantidad = 3
regulable = si
Barra
| Propiedad | Valores | Descripción |
|---|---|---|
altura | número mm | Distancia desde el techo de la celda |
material |
aluminioacero |
Tiradores
La propiedad tirador está disponible tanto en puertas como en cajones.
| Propiedad | Valores | Descripción |
|---|---|---|
tirador |
barrapomoperfilninguno |
Tipo de tirador |
longitud | número mm | Longitud de barra/perfil |
acabado |
cromadonegrodoradoacero |
|
posicion |
izquierdaderechaarribaabajocentro |
Posición del tirador en el frente |
A1 = puerta
tirador = barra
longitud = 160
acabado = negro
Defaults globales
Puedes definir propiedades por defecto para todos los elementos de un tipo
dentro del mueble, añadiendo un bloque puerta,
cajon o balda al mismo nivel
que distribucion.
mueble armario
ancho = 1200
...
puerta # todas las puertas por defecto:
bisagra = izquierda
tirador = barra
longitud = 160
cajon # todos los cajones por defecto:
cierre-suave = si
distribucion
columnas = 2
A1 = puerta # hereda bisagra=izquierda, tirador=barra
A2.bisagra = derecha # solo A2 sobreescribe la bisagra
B1 = cajon # hereda cierre-suave=si
Herencia y cascada
Las propiedades se heredan de lo más general a lo más específico. Lo más específico gana:
- Propiedades del bloque
mueble(nivel más alto) - Defaults globales de tipo (
puerta,cajon…) - Asignación de celda concreta (
A1 = puertacon sub-propiedades) - Excepción puntual
A1.bisagra = derecha(máxima prioridad)
mueble armario
tablero = roble # toda la carcasa en roble
puerta
bisagra = izquierda # todas las puertas: bisagra izquierda
tirador = barra
distribucion
A1..A2 = puerta # hereda bisagra=izquierda, tirador=barra
B1 = puerta
bisagra = derecha # B1 sobreescribe solo la bisagra
B1.tirador = ninguno # B1 sobreescribe el tirador
Composición de muebles
Puedes definir varios muebles en un mismo archivo escribiendo un bloque
mueble detrás de otro, ambos al nivel de indentación 0.
Cada uno genera su propia vista previa.
mueble base
ancho = 1200
alto = 850
fondo = 600
tablero = blanco
trasera = fino
zocalo = 100
distribucion
columnas = 4
filas = 1
A1..D1 = cajon
cantidad = 3
mueble superior
ancho = 1200
alto = 700
fondo = 380
tablero = blanco
trasera = fino
zocalo = no
coronacion = 40
distribucion
columnas = 4
filas = 1
A1..D1 = puerta
Variables
Define valores reutilizables con variable al nivel 0 del archivo.
Por ahora las variables son texto simple; en fases futuras podrán usarse en expresiones.
variable ancho-col = 400
mueble armario
ancho = 1200
distribucion
columnas = 3 A:400 B:400 C:resto # (uso directo de valor)
...
$ancho-col) está pendiente
de implementar. Por ahora define los valores directamente.
Bloque zona
Una zona es un rango contiguo de celdas (horizontal o vertical) al que se da entidad propia para asignarle una puerta estructural o un panel ciego que se renderiza como overlay sobre las celdas subyacentes. Las celdas debajo siguen siendo independientes (con sus baldas, cajones, etc.); la zona solo añade una capa visual encima.
En MuebleLab puedes crear zonas visualmente seleccionando varias celdas con Shift+clic y pulsando Crear zona en el panel de propiedades. Usa Ocultar puertas estructurales para configurar las celdas debajo.
zona <rango> <tipo>
nombre = <texto> # opcional
hojas = 1 | 2
bisagra = izquierda | derecha | arriba | abajo
tirador = barra | pomo | perfil | ninguno
cristal = si | no
mostrar = si | no # oculta el overlay sin eliminarlo
bisagra = arriba o abajo producen una
puerta abatible (basculante) de una sola hoja. Las dos hojas solo tienen
sentido con bisagra izquierda/derecha;
en bisagra horizontal el compilador fuerza hojas = 1.
mueble armario-columna
ancho = 600
alto = 2200
fondo = 580
distribucion
columnas = 1
filas = 3 1:700 2:700 3:resto
A1 = abierto # interior libre bajo la puerta
A2 = abierto
A3 = abierto
zona A1..A3 puerta
nombre = puerta-columna
hojas = 1
bisagra = izquierda
tirador = barra
mueble aparador
ancho = 1800
alto = 900
fondo = 500
distribucion
columnas = 3 A:400 B:resto C:400
filas = 1
A1 = abierto
B1 = cajon
C1 = abierto
zona A1 ciego
nombre = panel-izquierda
zona C1 ciego
nombre = panel-derecha
mueble alto-cocina
ancho = 600
alto = 400
fondo = 350
distribucion
columnas = 1
filas = 1
A1 = abierto
zona A1 puerta
nombre = puerta-abatible
bisagra = arriba # pivota por arriba; tirador queda abajo
tirador = perfil
Reglas de rango
- Rango de una sola celda:
A1 - Rango horizontal (misma fila):
A1..C1 - Rango vertical (misma columna):
A1..A3 - Los rangos diagonales o irregulares no son válidos
Tokens del bloque zona
| Token | Valores | Notas |
|---|---|---|
nombre | texto libre | nombre descriptivo (opcional) |
hojas | 1 / 2 | número de hojas de la puerta |
bisagra | izquierda / derecha / arriba / abajo | lado de apertura. arriba / abajo producen puerta abatible de 1 hoja |
tirador | barra / pomo / perfil / ninguno | |
cristal | si / no | puerta con vidrio |
mostrar | si / no | visibilidad del overlay (defecto: sí) |
Bloque montaje
El bloque montaje describe cómo se ensamblan las piezas
(tipo de uniones, herrajes, guías de cajón…). Está definido en la especificación
pero aún no se compila.
montaje
defecto = minifix # unión por defecto para todo
carcasa
union = minifix
separacion = 96
desde-canto = 37
balda
union = pivote
cajon
guia = extension-total
largo = auto
puerta
bisagra = cazoleta
Tipos de unión
| Token | Descripción |
|---|---|
minifix | Tornillo europeo tipo confirmat |
tubillon | Espiga de madera |
tornillo | Tornillo directo |
escuadra | Escuadra metálica |
pivote | Pivote para balda (sistema 32mm) |
grapa | Grapa neumática |
cola | Cola de madera |
ranura | Ranura fresada (dado) |
rebaje | Rebaje en el canto |
Ejemplos comentados
Galería de ocho muebles completos en MFL, cada uno con su vista 2D y el
código fuente íntegro. Los ficheros originales están en
mfl/ejemplos/.
01 · Armario clásico
Armario de pasillo con 3 columnas: dos altas con puertas + cajones debajo, y una columna lateral abierta para zapatos. Muestra el flujo completo: dimensiones, materiales, puerta como default global, distribución en grid, override por celda.
mueble armario_clasico
ancho = 1200
alto = 2200
fondo = 580
grosor = 19
tablero = roble
frente = roble
canto = fino
trasera = fino
zocalo = 80
puerta
bisagra = izquierda
tirador = barra
distribucion
columnas = 3 A:400 B:400 C:resto
filas = 3 1:1200 2:600 3:resto
A1 = puerta
A2 = puerta
A3 = cajon
cantidad = 2
B1 = puerta
B2 = puerta
B3 = cajon
cantidad = 2
C1..C3 = abierto
B1.bisagra = derecha
B2.bisagra = derecha
02 · Cocina alta suspendida
Módulo de pared para cocina, sin tablero inferior (cuelga de la pared con tornillos invisibles). Dos puertas verticales con tirador tipo perfil integrado. Muestra sin-suelo y módulo sin zócalo.
mueble cocina_alta
ancho = 600
alto = 720
fondo = 320
grosor = 19
tablero = blanco
frente = blanco
canto = fino
trasera = fino
sin-suelo = si
puerta
tirador = perfil
distribucion
columnas = 1
filas = 2 1:resto 2:resto
A1 = puerta
A2 = puerta
A1.bisagra = arriba
A2.bisagra = abajo
03 · Mueble bajo de TV
Mueble largo de salón: dos puertas a los lados (cajones internos escondidos) y un compartimento central abierto para TV + decodificador + barra de sonido. Acabado en nogal con tirador perfil.
mueble mueble_tv
ancho = 1800
alto = 500
fondo = 420
grosor = 19
tablero = nogal
frente = nogal
canto = fino
trasera = fino
zocalo = 60
puerta
tirador = perfil
distribucion
columnas = 3 A:400 B:resto C:400
filas = 1
A1 = puerta
B1 = abierto
C1 = puerta
A1.bisagra = izquierda
C1.bisagra = derecha
04 · Estantería abierta
Librería de salón sin frentes ni cajones — solo carcasa + 5 baldas regulables. Tablero grueso en pino para soportar carga. Sin zócalo, apoyada directamente en el suelo.
mueble estanteria
ancho = 900
alto = 1800
fondo = 280
grosor = 22
tablero = pino
canto = fino
trasera = fino
balda
regulable = si
distribucion
columnas = 1
filas = 5 1:resto 2:resto 3:resto 4:resto 5:resto
A1..A5 = balda
05 · Cómoda de cajones
Cómoda de dormitorio. Cuerpo en haya con frentes en blanco mate. Canto grueso (ABS 2mm) para resistir golpes en el dormitorio. Cierre suave en todos los cajones, tirador continuo tipo barra.
mueble comoda
ancho = 1000
alto = 900
fondo = 480
grosor = 19
tablero = haya
frente = blanco
canto = grueso
trasera = fino
zocalo = 80
cajon
tirador = barra
cierre-suave = si
distribucion
columnas = 1
filas = 4 1:resto 2:resto 3:resto 4:resto
A1 = cajon
A2 = cajon
A3 = cajon
A4 = cajon
06 · Vitrina con cristal
Vitrina de comedor: parte alta con dos puertas de cristal para vajilla expuesta, parte baja con cajones para mantelerías. Tirador tipo pomo clásico, trasera de tablero macizo (no HDF) para reforzar.
mueble vitrina
ancho = 800
alto = 1600
fondo = 380
grosor = 19
tablero = roble
frente = roble
canto = fino
trasera = tablero
zocalo = 80
puerta
cristal = si
tirador = pomo
distribucion
columnas = 2 A:400 B:resto
filas = 2 1:1100 2:resto
A1 = puerta
B1 = puerta
A2 = cajon
B2 = cajon
A1.bisagra = izquierda
B1.bisagra = derecha
07 · Armario con colgador
Armario de dormitorio. Dos columnas, cada una con barra de colgar arriba y zona de baldas/cajones abajo. Bloques zona definen las puertas como overlays estructurales que cubren toda la altura, independientes de la distribución interior de celdas.
mueble armario_ropa
ancho = 1400
alto = 2400
fondo = 580
grosor = 19
tablero = blanco
frente = blanco
canto = fino
trasera = fino
zocalo = 80
distribucion
columnas = 2 A:resto B:resto
filas = 2 1:1700 2:resto
A1 = barra
B1 = barra
A2 = balda
cantidad = 1
regulable = si
B2 = cajon
cantidad = 2
zona A1..A2 puerta
nombre = puerta_izq
bisagra = izquierda
tirador = perfil
zona B1..B2 puerta
nombre = puerta_dcha
bisagra = derecha
tirador = perfil
08 · Módulo en fila
Módulo bajo de salón pensado para integrarse en una fila — comparte lateral con el módulo siguiente (sin-lateral-dcha = si). Lleva tapa decorativa de madera con voladizo frontal e izquierdo, dejando el canto del módulo vecino como tope a la derecha.
mueble modulo_fila
ancho = 800
alto = 720
fondo = 580
grosor = 19
tablero = blanco
frente = blanco
canto = grueso
trasera = fino
zocalo = 80
sin-lateral-dcha = si
tapa = si
voladizo-izq = 30
voladizo-frente = 30
puerta
bisagra = izquierda
tirador = barra
distribucion
columnas = 2 A:400 B:resto
filas = 1
A1 = puerta
B1 = cajon
cantidad = 3