# Límites de la API .NET de Revit 2027 (LIM-06)

Inventario de **lo que se puede hacer en la interfaz de Revit y no por la API**, y de lo que la API permite **solo con condiciones**, sacado de las 201 pruebas ejecutadas (de 206) del [checklist](checklist-206-pruebas.md) (2026-10-17 a 2026-10-28, Revit 2027.1 build 27.1.0.45, .NET 10). Cada fila remite a su ID; el detalle y las evidencias están en el checklist.

Leyenda: **sin API** = no existe ninguna forma soportada; **atajo** = no hay método directo, pero hay un rodeo que funciona; **con condiciones** = la API existe pero tiene trampas que solo se ven ejecutando.

## 1. Sin API (la interfaz lo hace, el código no)

| Qué | ID | Detalle | ¿Atajo? |
|---|---|---|---|
| Crear **fases** | ELM-21 | `doc.Phases.Append` → "Collection is read-only"; `Phase` sin constructores públicos | No. Partir de una plantilla con las fases ya creadas |
| Crear **opciones de diseño** | ELM-20 | `DesignOption` solo expone lectura | No |
| Crear **scope boxes** | ELM-22 | Solo `PostableCommand.ScopeBox` (herramienta interactiva) | Copiar una existente con `ElementTransformUtils.CopyElements` (sin probar) |
| Crear **familias in situ** | ELM-23 | Solo `PostableCommand.ModelInPlace` (interactivo) | No; usar familias cargables o `DirectShape` |
| Crear una **leyenda** desde cero | VIS-02 | Sin método de creación | `View.Duplicate` de una leyenda que ya exista en la plantilla |
| Crear un **esquema de color** desde cero | VIS-12 | Sin método de creación | `ColorFillScheme.Duplicate` de uno de la plantilla ✅ |
| **Campos calculados** (fórmulas) en tablas | VIS-10 | `AddField(ScheduleFieldType.Formula)` → `ArgumentException` | No |
| **Render** fotorrealista | VIS-15 | Ningún método | No (`DirectContext3D` dibuja, no renderiza) |
| Texto en la **barra de estado** | UI-09 | Solo mostrarla u ocultarla | No |
| **Atajos de teclado** | UI-10 | Solo abrir el diálogo | No |
| **Unidades por defecto** de la aplicación y rutas de **plantillas** | UI-13 | No hay propiedad en `Application`; `DefaultProjectTemplate` y `FamilyTemplatePath` son de solo lectura | Unidades: `Document.SetUnits` por documento |
| Datos de **carbono incorporado** (`EmbodiedCarbonAsset`) | FAM-10 | El asset se crea y se enlaza al material, pero coeficiente, unidad y proveedor no se pueden escribir | No |
| Barra de **progreso** del add-in | CTX-10 | Solo `ProgressChanged` de la barra de Revit | Ventana WPF propia bombeando mensajes ✅ |
| **Deshacer / rehacer** | TRX-12 | No hay método `Undo` | `PostCommand(PostableCommand.Undo)` ✅ (asíncrono) |
| Modificar **pestañas nativas** de la cinta | UI-11 | Fuera de la API | `AdWindows.dll` lo permite, **sin soporte** ⚠️ |
| Exportar a **NWC** | EXP-04 | La API existe, pero el exportador no viene con Revit 2027 | Instalar el exportador de Navisworks |
| Abrir un **RVT fuera de Revit** | SHL-02 | `Application` no tiene constructor público | Solo metadatos: `BasicFileInfo.Extract` y lectura OLE de la vista previa ✅ (SHL-03, SHL-04) |
| **Hot Reload / Editar y continuar** de Visual Studio | DEV-00 | Los 89 `runtimeconfig.json` de Revit fijan `MetadataUpdater.IsSupported=false`; Editar y continuar falla **en silencio** | Contexto descargable (runner): ~4 s de guardar a resultado ✅ (DEV-03, DEV-09) |
| `BinaryFormatter` | ENT-15 | Revit lo habilita, pero .NET 10 lo eliminó: `PlatformNotSupportedException` | Migrar a `System.Text.Json` |

## 2. Con condiciones (existe, pero con trampas)

### Diálogos, hilos y contexto
| Trampa | ID | Qué hacer |
|---|---|---|
| Un **aviso** en una transacción de la API abre un diálogo **modal que bloquea la API** (146 s) | TRX-07, EXP-09 | `Application.FailuresProcessing` (lo aplica el runner) o `IFailuresPreprocessor` + `DeleteWarning` |
| Los **errores** propios (`FailureDefinition`) solo se pueden registrar **en el arranque**; resolverlos con `DeleteElements` funciona (se borra el elemento y se conserva el resto de la transacción) | TRX-08 |
| Las transacciones **internas** de Revit (importar IFC) no pasan por tu `IFailuresPreprocessor` | EXP-09 | `Application.FailuresProcessing` |
| `DialogBoxShowing.OverrideResult` cierra el diálogo, pero **ningún código acepta un aviso**: todos hacen rollback | EVT-06, EXP-12 | Sirve para no colgarse, no para aceptar |
| Un **`ExternalEvent` espera** a que se cierre cualquier diálogo modal | CTX-05 | Evitar diálogos durante los lotes |
| Las **lecturas** desde otro hilo no están protegidas (las escrituras sí) | CTX-01, CTX-03 | Todo por `ExternalEvent` |
| Tras un `await` el código vuelve al hilo principal pero **fuera de contexto**: no puede escribir | CTX-02 | `ExternalEvent` |
| 1.000 `Raise()` = **1 ejecución** | CTX-06 | Cola propia + un `Raise()` |
| `Idling`: 6.840 eventos/s en primer plano, 1 en 9 s en segundo plano | CTX-07 | No usarlo como temporizador |
| Una operación larga **congela Revit** | CTX-09 | Bombear mensajes cada 100 ms (−27 % de rendimiento, riesgo de reentrada) |
| Dos `PostCommand` seguidos: el segundo **lanza excepción** | UI-06 | Encadenar en órdenes separadas |

### Interfaz
| Trampa | ID |
|---|---|
| Un **panel acoplable** registrado en caliente **nunca se crea** (sin error); solo funciona en `OnStartup` | UI-03 |
| `PreviewControl` **modifica la cámara** de la vista real del proyecto | VIZ-04 |
| `TaskDialog` no admite a la vez casilla de verificación y casilla extra | UI-04 |
| `PickBox` devuelve las esquinas **sin ordenar** | UI-05 |
| `ExportImage` sigue el **tema** del lienzo (fondo oscuro) y no incluye la leyenda de AVF | UI-08, VIZ-03 |
| `Selection.SetElementIds` dispara `SelectionChanged` una sola vez y diferido | EVT-08 |

### Modelado, anotación y exportación
| Trampa | ID |
|---|---|
| `NewFootPrintRoof`: el `out` debe venir **inicializado** | ELM-04 |
| `CurtainGrid.AddGridLine(isU: true)` crea una línea **horizontal** | ELM-08 |
| Escaleras: Revit crea barandillas solas; L·huella da L+1 contrahuellas | ELM-09 |
| `NewSweep`: el perfil va en coordenadas **locales** | FAM-02 |
| `SpotDimension.ValueString` es **null** en cotas de elevación; usar `SPOT_ELEV_SINGLE_OR_UPPER_VALUE` | ANO-08 |
| `IndependentTag.Create`: **~300 ms por etiqueta** | ANO-04, LIM-07 |
| Cargar familias: ~280 ms por familia | FAM-07 |
| IFC y gbXML exigen una **transacción abierta**; gbXML, además, un modelo energético | EXP-03, EXP-05, DIS-05 |
| DGN: `Export` devuelve **false sin explicación** | EXP-05 |
| Codos MEP: la plantilla arquitectónica no trae los accesorios | DIS-01 |
| Armadura: firma nueva de `Rebar.CreateFromCurves`; espaciado `3@200;2@400` sin documentar | DIS-03 |
| `RevitLinkType.Create` falla en silencio si el RVT está abierto | EXP-08 |

### Carga de add-ins
| Trampa | ID |
|---|---|
| Por defecto todo va al **mismo contexto**: gana la versión de una dependencia que ya tenga Revit (Newtonsoft 13.0.1) | ENT-08, ENT-11 |
| El **aislamiento** (`UseRevitContext=False`) **funciona** en 2027 | ENT-09 ✅ |
| Compartir DLL entre contextos: `PublicAssemblies` con **ruta absoluta** (se resuelve contra el directorio de trabajo), `DependsOnContext` **sin** `AssemblyName`, y el proveedor debe cargar antes (orden alfabético) | ENT-10 |
| Add-ins de **2024 (.NET Framework 4.8)** y de 2026 (.NET 8) **cargan** en 2027 (con aviso en el journal) | ENT-04, ENT-05 |
| La ruta antigua `C:\ProgramData\…\Addins\2027` se **ignora** sin aviso; la de todos los usuarios es `C:\Program Files\Autodesk\Revit\Addins\2027` (hay que crearla como administrador) | ENT-02, ENT-03 |
| Una excepción en `OnStartup` muestra "External Tool Failure"; `Result.Failed`, **nada** | ENT-07 |

## 3. Estabilidad

| Hecho | ID |
|---|---|
| 💥 Crear/guardar/cerrar en bucle **tumba Revit** (`0xc0000005`) si se guarda en una carpeta vigilada por otros procesos (el repositorio con VS abierto: tras 8-9 ciclos). En `C:\…\AppData` aguantó 120 | EXP-10 |
| 💥 Un desbordamiento de pila mata Revit al instante (`0xc00000fd`) | DEV-11 |
| El archivo que se escribía en el momento del crash queda **corrupto** (16 KB, OLE vacío); los anteriores, íntegros | LIM-05 |
| Crear y deshacer 74.000 muros deja +1,2 GB que no se liberan | CTX-09 |
| 100 aperturas de RVT: +58 MB, sin fuga apreciable | EXP-13 |
| ⚠️ `Nice3point.TUnit.Revit` ejecuta la API **fuera de Revit.exe y sin cargar los módulos de licencias de Autodesk**: no se adoptó | ENT-12 |

## 4. Lo que sí funciona mejor de lo esperado

- **Falso hot reload** con contexto descargable: 3,8 s por iteración; con `lab vigilar` + `dotnet watch`, ~4 s de guardar a resultado (DEV-03, DEV-09). Un reinicio completo cuesta 37 s (DEV-01).
- **Interfaz en caliente**: cinta, botones, combos, sustitución de comandos nativos (`AddInCommandBinding`) y `DirectContext3D` se crean sin reiniciar Revit (UI-01, EVT-07, VIZ-02).
- **Lotes locales sin nube**: `Revit.exe <journal>` abre, ejecuta un comando del add-in y sale solo (ENT-13); dos instancias simultáneas dan ×1,5 de rendimiento con la licencia educativa (CTX-12).
- **Licencia educativa**: ninguna marca en PDF, DXF ni IFC (EXP-01, EXP-02, EXP-03).
- **Fuera de Revit**: geometría (`XYZ`, sólidos), `BasicFileInfo` y la vista previa del RVT funcionan en una consola .NET (SHL-01, SHL-03, SHL-04).
