Reglas de validación IFC con Python: del requisito a la prueba
«Las puertas deben estar bien informadas». Una instrucción magnífica para asentir en una reunión y completamente inútil para decidir qué comprobar. Qué puertas, qué dato, dónde buscarlo y qué resultado esperamos: alguien tendrá que concretarlo antes de pedirle a Python que reparta aprobados. Yo puedo explicar el recorrido; interpretar un acuerdo que nunca llegó a redactarse sigue fuera del alcance, por mucho entusiasmo que pongamos en la consola.
Aquí vamos a diseñar y probar una regla para los datos de una entrega IFC: un código de espacio con un formato acordado. El ejemplo recibe valores preparados y se ejecuta sin instalar IfcOpenShell; no abre un archivo. Esa separación permite aprender a formular el requisito y comprobar sus resultados antes de conectar la extracción. Si buscas leer el modelo, continúa después con la introducción a IfcOpenShell. Prefiero una regla que puedas discutir y poner a prueba a un supuesto validador universal cuya principal virtud sea el nombre.
Define una regla que otra persona pueda comprobar
Imagina una entrega en la que cada espacio incluido en el alcance debe llevar un código ESP- seguido de tres cifras ASCII. En este ejemplo inventado ESP-014 tendría formato válido y SALA14 no. El patrón no es una recomendación universal: el proyecto debe elegir su convención. Tampoco demuestra que el código exista en el registro de espacios. Esa segunda pregunta necesita consultar el registro y conviene conservarla como una comprobación distinta.
Falta definir la población. ¿Todos los IfcSpace del archivo son espacios de la entrega? Puede haber espacios exteriores, auxiliares o de fases excluidas. La regla necesita una forma estable de reconocer su alcance. Si utiliza una clasificación y esa clasificación falta, no debería declarar «no aplicable» por comodidad. Podría ser imposible decidir. Una máquina puede aprobar un modelo entero sin evaluar nada y mostrar el resultado con una serenidad que algunos departamentos comerciales envidiarían.
Hay que acordar también la ubicación del dato: atributo, propiedad de instancia o información heredada del tipo, según la convención del proyecto. No conviene buscar cualquier texto parecido y elegir el primero que tenga buena pinta. El adaptador que lee el IFC debe conocer el campo esperado, conservar lo recibido y explicar si no lo encuentra. Documenta un ejemplo correcto, uno incorrecto, otro fuera de alcance y otro cuyo alcance no pueda determinarse.
Esa ficha permite discutir la lógica sin leer Python. El responsable debe poder explicar qué objetos entran y qué valores se admiten. Si la conversación cambia al ver los ejemplos, hemos encontrado trabajo necesario antes de programar. No es tiempo perdido: es la parte que habría reaparecido después como una docena de falsas incidencias. El ordenador ejecutará la decisión que reciba, incluida la decisión mal formulada.
Separa la extracción de la evaluación
IfcOpenShell ofrece acceso a entidades y utilidades para consultar sus propiedades. Esa lectura localiza objetos y extrae información; la evaluación decide si el valor satisface nuestra regla. Separarlas permite comprobar la lógica con datos pequeños sin abrir un edificio completo cada vez. También ayuda a descubrir si un fallo procede del modelo, de la extracción o del criterio. Un único bucle enorme ahorra unas líneas y suele cobrar intereses al depurar.
La función del ejemplo recibe si el espacio está incluido, si se ha localizado el campo y el valor leído. Devuelve estado y mensaje. No abre IFC ni decide cómo se reconoce el alcance: eso corresponde al adaptador. Así podemos probar una propiedad ausente, un texto vacío y un número sin fabricar un modelo para cada intento. Que el valor recibido sea 14 no autoriza a convertirlo en ESP-014; estaríamos inventando parte del dato que pretendíamos revisar.
La normalización debe ser visible. Aquí solo se eliminan espacios en los extremos, conservando el original para el informe. No se cambian mayúsculas, no se rellenan cifras y no se adivinan caracteres. Podríamos acordar otras transformaciones, pero habría que documentarlas y probarlas. La función fullmatch de Python comprueba la cadena completa, evitando aceptar un código válido escondido en un texto más largo.
Este fragmento usa únicamente la biblioteca estándar y evalúa una regla de formato. Puedes ejecutarlo con datos inventados antes de conectarlo al archivo. La lectura del IFC y la detección de duplicados son pasos adicionales; el ejemplo no escribe en el modelo ni certifica el diseño.
Prueba los resultados y también su ausencia
Comprueba ESP-014, una cadena vacía, un número y un texto con prefijo o sufijo extra. Añade ESP- con cifras de otro conjunto de caracteres: este patrón exige las cifras ASCII del cero al nueve. Prueba un objeto excluido y otro con alcance desconocido. Cada entrada debe tener un resultado esperado escrito de antemano. Ejecutar la función y decidir después que lo que devuelve parece razonable es observación; todavía no demuestra que se esté aplicando el criterio previsto.
Después llega la integración: un IFC pequeño con espacios conocidos y datos colocados donde el adaptador espera encontrarlos. Debe incluir un campo ausente y otro vacío, porque son situaciones diferentes. Compara manualmente los objetos con el informe. La prueba de la función puede pasar perfectamente mientras el adaptador consulta otra propiedad. No hay contradicción: las dos piezas están contestando preguntas distintas y necesitan sus propias comprobaciones.
Controla cuántos objetos se encontraron, cuántos entraron en alcance y cuántos pudieron evaluarse. Si esperabas espacios y la consulta encuentra cero, hace falta investigar. Quizá el archivo no los contiene, quizá la selección está mal o la exportación cambió. Cero fallos no permite distinguir esas historias. El resumen debería mostrar cobertura y resultados, evitando «todo correcto» cuando la ejecución no ha llegado a hacer el trabajo previsto.
Si el archivo no se abre o falla una consulta, la ejecución debe declararlo. Capturar cualquier excepción y continuar como si faltara un código convierte un fallo de la herramienta en una acusación al modelo. La alternativa contraria es peor: saltarse la comprobación y emitir un aprobado. En ambos casos el informe parece completo porque ha desaparecido precisamente el dato que lo desmiente. Prefiero una interrupción que se pueda investigar a una tranquilidad fabricada con un bloque except.
Devuelve evidencia que permita corregir
Una fila útil identifica la revisión del archivo, el GlobalId del espacio, la regla y su versión, el campo consultado, el valor recibido y el resultado. Planta y nombre ayudan a localizarlo, pero no sustituyen la identidad del objeto. El informe debe explicar qué se observó y por qué incumple la condición. «Espacio mal» tiene la precisión de una nota adhesiva que dice «mirar tema»: alguien seguirá investigando desde cero.
El ejemplo solo comprueba formato. Para comprobar unicidad debes comparar códigos dentro del alcance acordado; para comprobar existencia necesitas el registro de referencia y su versión. Presenta esas comprobaciones por separado. Un código puede tener formato válido y estar duplicado o no existir. Fusionarlo todo bajo un único indicador oculta qué debe corregirse y dificulta comprobar si la solución resuelve el problema.
Después de corregir el modelo de autoría, revisa el nuevo IFC exportado. No basta con ver el parámetro bien en la aplicación: hay que confirmar que el mapeo lo conserva. Compara hallazgos persistentes, nuevos y resueltos, atendiendo a elementos desaparecidos y cambios de identificador. Si un espacio deja de exportarse, su fallo no debería celebrarse como una corrección sin comprobar por qué desapareció.
Guarda archivo, configuración y versiones junto al informe. Una huella del archivo puede ayudar a reconocer exactamente qué se procesó. Esa trazabilidad responde a la pregunta de por qué una entrega pasó y otra no, incluso meses después. La explicación no debería depender de encontrar el portátil donde vive «el script bueno». Los programas también necesitan una fuente reconocible, aunque su autor prometa que no ha tocado nada importante.
Amplía la automatización cuando la regla sea estable
Python compensa con repetición, volumen o necesidad de combinar información. No obliga a desarrollar todas las comprobaciones desde cero. IfcOpenShell documenta funciones de validación del esquema, y los requisitos que encajen en IDS pueden formalizarse para herramientas compatibles. Cada pieza responde a una pregunta: reglas del proyecto, conformidad del archivo y revisión del diseño no son garantías intercambiables.
Nuestra función revisa una convención de códigos. No decide si los espacios cumplen el programa funcional, si las superficies son correctas o si el edificio satisface la normativa. Eso requiere otras condiciones y responsables. Ampliar el sistema exige explicar esas dependencias, en lugar de añadir «inteligente» al nombre del informe. Una herramienta limitada y comprobada suele prestar más servicio que una promesa general que nadie sabe poner a prueba.
Empieza por una regla que otra persona pueda reproducir. Si ajustas condiciones al ver las primeras exportaciones, conserva los casos que motivaron el cambio para comprobarlos después. Así el conocimiento se transforma en pruebas y deja de esconderse en parches sucesivos. El progreso aparece cuando el siguiente archivo se revisa con un criterio más claro, no cuando el script ocupa más páginas.
Antes de conectar más reglas, comprueba que el informe distingue un incumplimiento de un caso no evaluado y que permite volver al elemento correcto. Dar a todos el mismo color rojo ahorra columnas, pero transfiere la investigación a quien recibe el archivo. La automatización debería quitarle trabajo. ¿Qué caso dudoso de tus entregas impide ahora escribir una condición clara?
Respuestas