En algún momento de los últimos años, alguien de tu equipo exportó capturas de pantalla de un modelo BIM y las adjuntó a un correo. No porque no hubiera una manera mejor. Sino porque la manera mejor requería que el receptor tuviera instalado un software de varios miles de euros al año — que el cliente no tiene, que el jefe de obra no usa, que el facility manager nunca va a comprar.
Ese ha sido, durante décadas, el límite real del BIM: no la calidad de los modelos, sino quién puede abrirlos.
IFC.js es la respuesta técnica a ese límite. Es una librería open source escrita en JavaScript que permite cargar, visualizar e interrogar modelos IFC directamente en el navegador — sin plugins, sin instalaciones, sin licencias. La misma tecnología que usa Google Maps o Figma aplicada al modelo BIM: renderizado con WebGL, parseo con WebAssembly, y acceso completo a las propiedades de cada elemento.
El resultado práctico es que cualquier persona con un navegador puede hacer clic en una viga y ver su tipo de acero, navegar planta a planta, aislar las instalaciones de climatización o medir una distancia. Sin que el coordinador BIM tenga que estar presente para abrir el archivo.
En este artículo construimos un visor BIM funcional desde cero con React y Next.js, con selección de elementos y sus propiedades BIM, filtrado por disciplina, y las optimizaciones necesarias para que funcione con modelos reales.
¿Qué es IFC.js y por qué importa?
IFC.js es una librería JavaScript open source que permite cargar, visualizar y consultar modelos IFC directamente en el navegador, sin necesidad de instalar Revit, Navisworks ni ningún plugin. Se basa en Three.js para el renderizado WebGL y en WebAssembly para parsear el formato IFC.
Lo que lo diferencia de otras soluciones de visualización web es que preserva la semántica del modelo: no convierte el IFC a un mesh sin información, sino que mantiene el acceso a las propiedades BIM de cada elemento. Puedes hacer clic en una viga y obtener su tipo de acero, su longitud exacta, su fase de construcción. Esa información es la que hace útil un visor BIM — sin ella, es solo un modelo 3D bonito.
| Característica | IFC.js | Formato GLTF/OBJ | Autodesk Viewer (APS) |
|---|---|---|---|
| Preserva propiedades IFC | ✅ | ❌ | ✅ |
| Sin licencia de uso | ✅ | ✅ | ❌ (requiere cuenta APS) |
| Sin conversión previa | ✅ | ❌ | ❌ |
| Rendimiento con 500 MB+ | Requiere optimización | ✅ | ✅ |
| Self-hosted | ✅ | ✅ | ❌ |
Instalación
npm install web-ifc-three web-ifc three
También necesitas copiar los archivos WASM al directorio público:
cp node_modules/web-ifc/*.wasm public/
Los archivos .wasm son los que hacen posible el parseo de IFC en el navegador. Sin ellos, el modelo no cargará.
Configuración básica con React
import { useEffect, useRef } from 'react'; import * as THREE from 'three'; import { IFCLoader } from 'web-ifc-three'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; export default function VisorBIM() { const mountRef = useRef<HTMLDivElement>(null); useEffect(() => { const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); mountRef.current?.appendChild(renderer.domElement); // Iluminación const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); const directionalLight = new THREE.DirectionalLight(0xffffff, 1); directionalLight.position.set(10, 10, 5); scene.add(ambientLight, directionalLight); // Cargar IFC const loader = new IFCLoader(); loader.ifcManager.setWasmPath('/'); loader.load('/modelo.ifc', (model) => { scene.add(model); }); camera.position.set(10, 10, 10); const controls = new OrbitControls(camera, renderer.domElement); const animate = () => { requestAnimationFrame(animate); controls.update(); renderer.render(scene, camera); }; animate(); return () => renderer.dispose(); }, []); return <div ref={mountRef} className="w-full h-screen" />; }
Este es el esqueleto mínimo. En menos de 50 líneas tienes un visor 3D funcional capaz de cargar cualquier modelo IFC estándar.
Consultar propiedades de elementos
Una de las funcionalidades más potentes — y la que marca la diferencia frente a un simple visor 3D — es poder hacer clic en un elemento y obtener sus propiedades BIM:
const getElementProperties = async (event: MouseEvent) => { const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2( (event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1 ); raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObjects(scene.children, true); if (intersects.length > 0) { const expressID = await loader.ifcManager.getExpressId( intersects[0].object.geometry, intersects[0].faceIndex! ); const props = await loader.ifcManager.getItemProperties(0, expressID); console.log(props); } };
El expressID es el identificador único de cada elemento en el archivo IFC. A partir de él puedes recuperar todas sus propiedades: tipo, material, Psets, relaciones con otros elementos y metadatos personalizados del modelo.
Filtrado por disciplina
Puedes filtrar los elementos visibles por categoría IFC para separar disciplinas y reducir la carga cognitiva del modelo:
// Ocultar instalaciones MEP const hideMEP = async () => { const mepCategories = [ IFCDUCTFITTING, IFCPIPEFITTING, IFCFLOWSEGMENT, ]; for (const category of mepCategories) { const ids = await loader.ifcManager.getAllItemsOfType(0, category, false); loader.ifcManager.createSubset({ modelID: 0, ids, material: transparentMaterial, scene, removePrevious: false, }); } };
Esta capacidad es especialmente valiosa en reuniones de coordinación: puedes mostrar solo la estructura, solo MEP, o cualquier combinación de disciplinas sin recargar el modelo.
Rendimiento con modelos grandes
Para modelos IFC de más de 100 MB, la configuración básica puede resultar lenta o consumir demasiada memoria. Estas son las optimizaciones más efectivas:
- Streaming: Usa
setOptimizeCoordspara reducir el uso de memoria en geometrías complejas - Web Worker: Parsea el IFC en un worker separado para no bloquear el hilo principal durante la carga
- LOD dinámico: Reduce la geometría de elementos lejanos a la cámara; impacto notable en modelos con alta densidad de elementos
- Frustum culling: Three.js lo gestiona automáticamente, pero verifica que
mesh.frustumCulled = trueen tus meshes personalizados
Para modelos por encima de 500 MB — habitual en proyectos de infraestructura — la estrategia más efectiva es dividir el modelo por disciplinas o zonas y cargarlas bajo demanda. La carga total de un IFC de 500 MB en un solo paso no es viable en el navegador actual.
Integración con Next.js
El principal reto con Next.js es que IFC.js usa APIs del navegador (WebGL, WebAssembly) que no están disponibles durante el Server Side Rendering. La solución es cargarlo dinámicamente, solo en el cliente:
const VisorBIM = dynamic(() => import('@/components/VisorBIM'), { ssr: false, loading: () => <div>Cargando modelo...</div>, });
Si usas Next.js 15+ con App Router, la directiva 'use client' en el componente del visor es suficiente para la mayoría de los casos. El dynamic con ssr: false es necesario cuando el componente se importa desde un Server Component.
Casos de uso reales
El valor de IFC.js no está solo en el aspecto técnico. Está en lo que permite hacer que antes no era posible:
Revisiones con el cliente — En lugar de exportar capturas de pantalla o PDFs, el equipo comparte un enlace al visor. El cliente puede explorar el modelo, marcar dudas y comentarlas en contexto. El tiempo de reunión se invierte en decisiones, no en navegación.
Coordinación en obra — El jefe de obra accede al modelo desde tablet en campo. Puede ver la sección exacta de la zona donde está trabajando, consultar las propiedades de los elementos y verificar cotas sin depender del equipo de oficina.
CDEs personalizados — Una plataforma de gestión documental propia puede integrar el visor directamente, vinculando modelos con planos, especificaciones y registros de mantenimiento en una sola interfaz.
Conclusión
IFC.js democratiza el acceso al BIM. Cualquier persona con un navegador puede explorar un modelo sin instalar nada, sin licencias y sin formación específica en herramientas propietarias. Para los equipos AECO, eso significa poder incluir en el proceso digital a todos los stakeholders — no solo a quienes tienen el presupuesto para comprar Revit.
El coste de entrada es bajo: unas horas de configuración y un modelo IFC exportado desde cualquier herramienta compatible con el estándar abierto. El potencial, en cambio, es transformador.