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:

MFL — ejemplo mínimo
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.

El bloque 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 vs. incorrecto
# ✅ 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

Estructura completa
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

PropiedadValoresNotas
anchonúmero mmAncho exterior total
altonúmero mmAlto exterior total
fondonúmero mmFondo exterior total
grosornúmero mmGrosor del tablero. Defecto: 18mm

Materiales y acabados

tablero — material de la carcasa

ValorDescripción
blanconegrogrisgrafitoaluminio
Colores lisos
roblepinohayanogal
Veteados de madera
tablero = roble 18mmPuedes añadir el grosor en mm

frente — material de puertas y cajones

Acepta los mismos valores que tablero, más:

matebrillo
tablero = roble          # carcasa en roble
frente  = blanco mate    # puertas blanco mate

canto

ValorDescripción
finoCanto de melamina 0.4mm
gruesoCanto ABS 2mm

trasera

ValorDescripción
finoHDF 6mm
tableroMismo 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.

PropiedadValoresDescripción
zocalo Hnúmero mm / noAltura del zócalo (inline). zocalo no lo desactiva.
altonúmero mmAlternativa al inline (dentro del bloque)
retranqueo / frontalnúmero mmRetranqueo frontal (defecto: 60mm)
lateralnúmero mmRetranqueo en los laterales
traseronúmero mmRetranqueo 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

PropiedadValoresDescripción
coronacion Hnúmero mm / noAltura del remate superior (inline).
altonúmero mmAlternativa 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.

PropiedadValoresDescripción
patas Nnúmero (cantidad)Activa N patas. Sin valor: 4 por defecto. patas no las desactiva.
altonúmero mmAltura de las patas
gruesonúmero mmSección cuadrada
cantidad4 / 5 / 6Alternativa al inline. 4=esquinas, 5=+centro, 6=+2 centrales
retranqueonúmero mmRetranqueo desde el canto
anclajetornillo / inserto / pegadoTipo 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
El compilador genera la tornillería correspondiente automáticamente y la añade al despiece de herrajes:
  • 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).
El check estructural avisa si se usa pegado en mueble grande (cara frontal > 1 m²) por riesgo de despegue.

Ruedas

Mismo patrón que patas:

PropiedadValoresDescripción
ruedas N2 / 4Activa N ruedas (inline). ruedas no las desactiva.
cantidad2 / 4Alternativa 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:

ConceptoAdjetivo (con género)Infinitivo (canónico)
Frente solapado al huecosolapada · solapadosolapar
Frente embutido en el huecoembutida · embutidoembutir
Trasera con ranura fresadaranurada · ranuradoranurar

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).

Consultas simples

SintaxisDevuelve
A1Resumen de la celda (tipo, propiedades).
A1.bisagraValor de una propiedad concreta.
A1.ancho / A1.altoDimensiones reales de la celda en el lienzo.
muebleResumen del mueble (dimensiones, distribución, construcción, zonas).
lateral-izq, techo, suelo, tapa, fondo, zocalo, coronacionDescripció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:

ObjetoPropiedades
mueble · <nombre del mueble>ancho, alto, fondo, grosor, interior_ancho, interior_alto, interior_fondo
lateral_izq · lateral_dchaancho, alto, fondo
techo · sueloancho, alto, fondo
tapaancho, alto, fondo, voladizo_izq, voladizo_dcha, voladizo_frente, voladizo_trasero
fondo (trasera)ancho, alto, grosor
zocaloalto, retranqueo
armazonposte, 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

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

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

TipoCuándo
L-cornerEsquina del mueble (lateral con techo o suelo)
T-jointDivisor interno apoya en lateral o en otro divisor
crossDos divisores se cruzan en el interior
buttCaso 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.

PropiedadValoresDescripción
construccioncaja / armazonModo de fabricación (defecto: caja). En bloque: construccion armazon inline.
postenúmero mmSección cuadrada del poste (defecto: 35 mm)
lateralnúmero mmGrosor del panel lateral encastrado (defecto: 10 mm)
travesanonúmero mmAltura del travesaño horizontal (defecto: 30 mm)
ranuranúmero mmProfundidad 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.

PropiedadEfecto
sin-lateral-izq = siOmite el panel lateral izquierdo
sin-lateral-dcha = siOmite el panel lateral derecho
sin-techo = siOmite el tablero superior
sin-suelo = siOmite 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í.

PropiedadValoresDescripción
cornisa Hnúmero mm o (bloque)Activa cornisa. Inline = altura. cornisa no desactiva.
altonúmero mmAltura de la moldura (defecto: 35 si no inline)
perfilescalonrectoredondocurvocoronagolaForma de la sección de la moldura
voladizonúmero mmSaliente 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
Despiece: la cornisa NO es rectangular — se cuenta por metros lineales con su perfil. El frontal mide 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.

PropiedadValoresDescripción
marco Hnúmero mm o (bloque) o noActiva marco. Inline = altura del tablero superior. marco no desactiva.
superior / tablero-superiornúmero mmAlto del tablero superior del marco
entrenúmero mmSeparación entre puertas
lateralnúmero mmSeparació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
El tablero superior se añade al despiece como “Tablero superior frontal” (ancho-interior × alto × T) y se fija a los laterales con 4 confirmats (2 por cada extremo).

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.

PropiedadValoresDescripción
largueros(bloque)Activa ambos por defecto. Sus props anidadas afinan.
superiorsi / noLarguero superior trasero (dentro de bloque)
inferiorsi / noLarguero inferior trasero (dentro de bloque)
altonúmero mmAltura del larguero (defecto: 80 mm)
gruesonúmero mmGrosor — 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
Cada larguero se fija a los dos laterales con 4 confirmats (2 por cada extremo). Suficiente para soportar el peso del mueble sin fondo. Aparecen en el despiece como “Larguero trasero superior/inferior” con dimensiones 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

PropiedadValoresDescripción
doble-carasi / noActiva el modo doble cara (default: no)
anclajesuelo / pared / techo / ningunoIndica 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:

ReglaAcción / Aviso
DefaultLarguero superior + inferior activados (hasTopRail/hasBottomRail)
Con encimera = siSe omite el larguero superior (la encimera maciza ya cose el conjunto)
Con anclaje = sueloSe omite el larguero inferior (el anclaje al suelo ya estabiliza)
Con anclaje = techoSe omite el larguero superior
alto > 1400 sin encimera/anclajeWarning: “añade larguero intermedio o anclaje exterior”
alto > 1800 sin encimera/anclajeWarning de vuelco crítico
fondo > 600Aviso: costados largos pueden pandear, considera refuerzo a media profundidad
fondo > 700Aviso: añadir hilera central de apoyos bajo la junta de fondos
ancho > 1600 + pocas patasSugerencia: añadir apoyos cada ~80 cm
ratio alto/fondo > 5Aviso 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.

Ver el ejemplo completo en 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.

PropiedadValores
tapa / tapa noActiva o desactiva la tapa
izq / izquierdanúmero mm — vuelo lateral izquierdo
dcha / derechanúmero mm — vuelo lateral derecho
frentenúmero mm — vuelo frontal
traseronú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.

PropiedadValores
encimerasi / 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.

Estructura del bloque
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.

Mueble TV: A y C enteras, B partido en 3
distribucion
  columnas = 3
  filas    = 1
  A1 = puerta
  B1 = abierto
  B1.dividir-horizontal = 3
  C1 = puerta
PropiedadValorEfecto
dividir-horizontalnúmero > 1Divide la celda en N filas internas. El resto de columnas se extienden con rowSpan = N.
dividir-verticalnúmero > 1Divide la celda en N columnas internas. El resto de filas se extienden con colSpan = N.
Equivale a escribir 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:

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.

Equivalentes
# 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

Tipos de contenido

TipoDescripción
puertaPuerta batiente
cajonCajón o bloque de cajones
baldaBalda fija o regulable
barraBarra de colgar ropa
abiertoEspacio libre sin elemento (defecto)
falso-frentePanel decorativo sin función
ciegoPanel tapón sin bisagra ni tirador

Puerta

PropiedadValoresDescripción
bisagra
izquierdaderechaarribaabajo
Lado de la bisagra. Defecto: izquierda
hojas1 / 2Puerta 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).
cristalsi / noPuerta con cristal
espejosi / noPuerta con espejo
cierre-suavesi / noAmortiguador de cierre
kitsi / noPuerta comprada hecha — no se fabrica nada en taller. Las bisagras se siguen contando
tiradorver 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

PropiedadValoresDescripción
cantidadnúmeroNúmero de cajones en el bloque
separacionnúmero mmSeparación entre frentes (defecto: 2mm)
estilo
superpuestoencastrado
Frente del cajón superpuesto (sobresale) o encastrado (a ras). Sinónimos: solapado/embutido.
espejosi / noFrente del cajón con espejo
cierre-suavesi / noGuías con amortiguador
pushsi / noApertura por presión, sin tirador
kitsi / noCuerpo del cajón comprado (laterales, fondo, base, correderas) — solo se fabrica el frontal de madera
tiradorver 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

PropiedadValoresDescripción
cantidadnúmeroNúmero de baldas (divide la celda horizontalmente)
regulablesi / noSistema 32mm
C1 = balda
  cantidad  = 3
  regulable = si

Barra

PropiedadValoresDescripción
alturanúmero mmDistancia desde el techo de la celda
material
aluminioacero

Tiradores

La propiedad tirador está disponible tanto en puertas como en cajones.

PropiedadValoresDescripción
tirador
barrapomoperfilninguno
Tipo de tirador
longitudnúmero mmLongitud 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.

Defaults que se aplican a todos los elementos de ese tipo
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:

  1. Propiedades del bloque mueble (nivel más alto)
  2. Defaults globales de tipo (puerta, cajon…)
  3. Asignación de celda concreta (A1 = puerta con sub-propiedades)
  4. 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)
    ...
La sustitución automática de variables ($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.

Sintaxis
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.

Armario columna con puerta que cubre 3 filas
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
Aparador con panel ciego en columna lateral
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 con puerta abatible (bisagra arriba)
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

Tokens del bloque zona

TokenValoresNotas
nombretexto librenombre descriptivo (opcional)
hojas1 / 2número de hojas de la puerta
bisagraizquierda / derecha / arriba / abajolado de apertura. arriba / abajo producen puerta abatible de 1 hoja
tiradorbarra / pomo / perfil / ninguno
cristalsi / nopuerta con vidrio
mostrarsi / novisibilidad 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.

Sintaxis prevista (pendiente de compilar)
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

TokenDescripción
minifixTornillo europeo tipo confirmat
tubillonEspiga de madera
tornilloTornillo directo
escuadraEscuadra metálica
pivotePivote para balda (sistema 32mm)
grapaGrapa neumática
colaCola de madera
ranuraRanura fresada (dado)
rebajeRebaje 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.

Vista 2D del armario clásico
MFL · 01-armario-clasico.mfl
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.

Vista 2D de la cocina alta suspendida
MFL · 02-cocina-alta-suspendida.mfl
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.

Vista 2D del mueble bajo de TV
MFL · 03-mueble-tv-bajo.mfl
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.

Vista 2D de la estantería abierta
MFL · 04-estanteria-abierta.mfl
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.

Vista 2D de la cómoda de cajones
MFL · 05-comoda-cajones.mfl
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.

Vista 2D de la vitrina con cristal
MFL · 06-vitrina-cristal.mfl
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.

Vista 2D del armario con colgador
MFL · 07-armario-ropa-barra.mfl
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.

Vista 2D del módulo en fila con voladizo
MFL · 08-modulo-fila-voladizo.mfl
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