Todos los artículos

Dentro de Kansumi: cómo un plano se convierte en un scene graph

Un recorrido técnico por el grafo de escena JSON de cada render de Kansumi, y qué miden realmente sus puntuaciones de confianza.

The Kansumi Team4 min
En esta página

La mayoría de las herramientas de IA para interiorismo tratan tu plano como una imagen. Kansumi lo trata como datos. En cuanto termina la extracción, tu plano deja de ser píxeles y se convierte en un documento JSON versionado que llamamos el scene graph (o grafo de escena): cada muro que arrastras, cada puerta que mueves y cada render que generas lee y escribe ese documento, nunca la imagen.

Este artículo recorre cómo funciona todo esto y por qué hace que los renders sean fiables.

El pipeline de Kansumi, desde la subida del plano hasta los renders, con el grafo de escena como única fuente de verdad
El pipeline de Kansumi, desde la subida del plano hasta los renders, con el grafo de escena como única fuente de verdad

Por qué las imágenes son una mala fuente de verdad

Una imagen de un plano no sabe nada. No puede decirte la longitud de un muro, si una puerta abre hacia dentro o si el sofá que pediste realmente cabe. Las herramientas que editan la imagen tienen que volver a adivinar todo eso en cada cambio, y así es como acabas con renders en los que la habitación gana un metro sin que nadie se dé cuenta.

Si la geometría no se guarda en ningún sitio, cada edición es un nuevo acto de imaginación.

Así que la guardamos. Toda.

El grafo de escena, en milímetros

Cada proyecto tiene su propio documento scene.v1.json. Todas las coordenadas y longitudes son enteros en milímetros del mundo real: no hay unidades de píxel en ningún sitio después de la extracción. Aquí tienes un fragmento reducido de una escena real:

scene.v1.json (excerpt)
{
  "schema_version": "v1",
  "units": "mm",
  "scale": {
    "confirmed": true,
    "reference": { "type": "wall_length", "element_id": "wall_a", "value_mm": 4200 }
  },
  "walls": [
    {
      "id": "wall_a",
      "start": { "x": 0, "y": 0 },
      "end": { "x": 4200, "y": 0 },
      "thickness_mm": 120,
      "confidence": 0.94,
      "user_confirmed": true
    }
  ],
  "openings": [
    {
      "id": "door_1",
      "kind": "door",
      "host_wall_id": "wall_a",
      "offset_mm_from_start": 2050,
      "width_mm": 900,
      "swing": "left",
      "swing_direction": "in",
      "confidence": 0.81,
      "user_confirmed": false
    }
  ]
}

Dos detalles de ese fragmento concentran la mayor parte del peso.

Los huecos se vinculan a los muros de forma paramétrica

Una puerta no se guarda como una posición (x, y). Se guarda como «en wall_a, a 2050 mm desde su inicio, con 900 mm de ancho». Cuando arrastras un muro, lo divides o lo enderezas en el editor, la puerta se reancla de forma determinista: no puede desplazarse hacia el centro de la habitación.

Un hueco de puerta definido por su muro anfitrión, el desplazamiento desde el inicio del muro y el ancho, todo en milímetros
Un hueco de puerta definido por su muro anfitrión, el desplazamiento desde el inicio del muro y el ancho, todo en milímetros

La escala es un ciudadano de primera clase

La extracción calcula una proporción provisional de píxeles a milímetros, pero la escena registra si una persona la ha confirmado, y contra qué referencia: la longitud conocida de un muro, una cota reconocida por OCR o el ancho estándar de una puerta. Hasta que scale.confirmed sea true, el editor la muestra, con honestidad, como una estimación.

Qué miden realmente las puntuaciones de confianza

Cada elemento extraído lleva una confidence entre 0 y 1. No es decoración: el editor ordena su cola de revisión según ese valor, y el pipeline se niega a renderizar a partir de geometría que sea a la vez de baja confianza y sin revisar.

ElementoOrigen de la confianzaPor debajo del umbral…
MurosConsenso del modelo de visión entre pasadasSe resalta para revisión en el editor
HuecosPuntuación de detección × confianza del muro anfitriónTe pedimos que confirmes el sentido de apertura y el ancho
HabitacionesCierre del polígono + concordancia con la etiqueta OCRSe deja sin definir el tipo de habitación
CotasCalidad del OCR sobre la etiqueta impresaSe ignora la etiqueta para la escala

Editar sin romper la geometría

Como el grafo de escena es el registro, las operaciones del editor son funciones puras y pequeñas sobre él. Dividir un muro, por ejemplo, reancla cada hueco mediante aritmética, no mediante una nueva detección:

wall-split (simplified)
function splitWall(scene: SceneV1, wallId: string, at_mm: number): SceneV1 {
  const wall = scene.walls.find((w) => w.id === wallId);
  if (!wall) throw new Error(`unknown wall: ${wallId}`);

  const [left, right] = divideSegment(wall, at_mm);

  const openings = scene.openings.map((o) => {
    if (o.host_wall_id !== wallId) return o;
    // An opening before the cut stays on the left piece with its offset
    // untouched; one after the cut moves to the right piece, offset shifted.
    return o.offset_mm_from_start < at_mm
      ? { ...o, host_wall_id: left.id }
      : { ...o, host_wall_id: right.id, offset_mm_from_start: o.offset_mm_from_start - at_mm };
  });

  return { ...scene, walls: replaceWall(scene.walls, wallId, [left, right]), openings };
}

Deshacer y rehacer salen gratis: cada edición genera un nuevo documento de escena, así que el historial no es más que una pila de ellos.

Los renders son recibos, no suposiciones

Cuando generas conceptos, el renderizador no mira en absoluto tu imagen subida. Construye una imagen de control a partir del grafo de escena (muros, huecos y las huellas de los muebles proyectadas desde la cámara canónica de la habitación) y condiciona el modelo de difusión con eso. El render coincide con tus dimensiones porque nunca se le mostró otra cosa.

Por eso también el editor de chat puede decirte «el sofá de 1.6 m no cabe en el muro de 1.4 m» en lugar de renderizar en silencio una habitación imposible: comprobar si algo cabe es aritmética de enteros en milímetros, verificada antes de generar un solo píxel.

Ideas clave

  • La geometría vive en un solo lugar: un grafo de escena en JSON versionado, en milímetros, nunca en píxeles.
  • Las relaciones son paramétricas: los huecos pertenecen a los muros, las cámaras pertenecen a las habitaciones, así que las ediciones se combinan con seguridad.
  • La incertidumbre es explícita: las puntuaciones de confianza y los indicadores user_confirmed controlan qué renderiza el pipeline.
  • Los renders se derivan del grafo: por eso coinciden con tu cinta métrica.

Si todavía no lo has probado, sube un plano y observa cómo se construye el grafo de escena ante tus ojos.

Sigue leyendo