Skip to main content

ifc-python

Leer, modificar y exportar archivos IFC con IfcOpenShell. Extrae elementos, propiedades, geometría y metadatos de modelos BIM. Usa cuando el usuario diga "IFC", "IfcOpenShell", "modelo IFC", "propiedades IFC", "exportar IFC", "leer IFC", "interoperabilidad BIM", "open BIM".

معلومات المصدر

المستودع
Umbral-Bot/umbral-agent-stack
آخر نشاط في المصدر
٤ مارس ٢٠٢٦ في ٢٣:٥٣
لغة SKILL.md المكتشفة
الإسبانية
النجوم
٠
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
ifc-python
description
Leer, modificar y exportar archivos IFC con IfcOpenShell. Extrae elementos, propiedades, geometría y metadatos de modelos BIM. Usa cuando el usuario diga "IFC", "IfcOpenShell", "modelo IFC", "propiedades IFC", "exportar IFC", "leer IFC", "interoperabilidad BIM", "open BIM".
metadata
{"openclaw":{"emoji":"🏗️","requires":{"env":"[Truncated]"}}}
# IFC Python Skill — IfcOpenShell y herramientas open BIM Rick usa este skill para leer, analizar, modificar y exportar archivos IFC (Industry Foundation Classes) usando IfcOpenShell y herramientas Python open source. ## Instalación y setup ```bash pip install ifcopenshell ``` IfcOpenShell soporta IFC2x3, IFC4 e IFC4x3. La versión de Python debe coincidir con la del paquete (3.9-3.12). Para geometría y visualización: ```bash pip install ifcopenshell[geometry] pip install OCC # Open CASCADE para renderizado ``` Paquetes complementarios: | Paquete | Uso | |---------|-----| | `ifcopenshell` | Lectura, escritura y modificación de IFC | | `ifcpatch` | Transformaciones batch sobre archivos IFC | | `ifcdiff` | Comparación entre versiones de modelos IFC | | `ifcclash` | Detección de interferencias geométricas | | `ifccsv` | Exportar/importar propiedades IFC a CSV | | `bimtester` | Validación de requisitos BIM con Gherkin | ## Abrir y explorar un modelo IFC ```python import ifcopenshell ifc = ifcopenshell.open("modelo.ifc") print(f"Schema: {ifc.schema}") # IFC2X3, IFC4, IFC4X3 print(f"Nombre: {ifc.header.file_name.name}") print(f"Elementos totales: {len(ifc.by_type('IfcProduct'))}") ``` ### Resumen de elementos por tipo ```python from collections import Counter tipos = Counter(e.is_a() for e in ifc.by_type("IfcProduct")) for tipo, cantidad in tipos.most_common(): print(f" {tipo}: {cantidad}") ``` Salida típica: ``` IfcWallStandardCase: 142 IfcDoor: 87 IfcWindow: 64 IfcSpace: 38 IfcColumn: 24 IfcSlab: 18 IfcBeam: 12 ``` ## Extraer propiedades de elementos ### IfcPropertySet y IfcPropertySingleValue ```python def get_properties(element): """Extrae todas las propiedades de un elemento IFC como dict.""" props = {} for definition in element.IsDefinedBy: if definition.is_a("IfcRelDefinesByProperties"): pset = definition.RelatingPropertyDefinition if pset.is_a("IfcPropertySet"): for prop in pset.HasProperties: if prop.is_a("IfcPropertySingleValue"): value = prop.NominalValue.wrappedValue if prop.NominalValue else None props[prop.Name] = value return props wall = ifc.by_type("IfcWall")[0] props = get_properties(wall) for name, value in props.items(): print(f" {name}: {value}") ``` ### Quantity Sets (cantidades) ```python def get_quantities(element): """Extrae IfcElementQuantity (áreas, volúmenes, longitudes).""" quantities = {} for definition in element.IsDefinedBy: if definition.is_a("IfcRelDefinesByProperties"): qset = definition.RelatingPropertyDefinition if qset.is_a("IfcElementQuantity"): for q in qset.Quantities: if q.is_a("IfcQuantityArea"): quantities[q.Name] = q.AreaValue elif q.is_a("IfcQuantityVolume"): quantities[q.Name] = q.VolumeValue elif q.is_a("IfcQuantityLength"): quantities[q.Name] = q.LengthValue return quantities slab = ifc.by_type("IfcSlab")[0] print(get_quantities(slab)) # {'NetArea': 45.2, 'GrossVolume': 9.04, 'Width': 0.2} ``` ## Filtrar elementos por tipo ```python # Muros walls = ifc.by_type("IfcWall") # Puertas doors = ifc.by_type("IfcDoor") # Espacios (habitaciones, zonas) spaces = ifc.by_type("IfcSpace") # Elementos estructurales columns = ifc.by_type("IfcColumn") beams = ifc.by_type("IfcBeam") slabs = ifc.by_type("IfcSlab") # Instalaciones MEP ducts = ifc.by_type("IfcDuctSegment") pipes = ifc.by_type("IfcPipeSegment") # Todos los elementos con geometría products = ifc.by_type("IfcProduct") ``` ### Filtrar por atributo ```python # Muros de un nivel específico level_2_walls = [ w for w in ifc.by_type("IfcWall") if any( rel.RelatingStructure.Name == "Nivel 2" for rel in getattr(w, "ContainedInStructure", []) ) ] # Elementos por GlobalId element = ifc.by_guid("2O2Fr$t4X7Zf8NOew3FLOH") ``` ## Exportar a CSV/JSON para análisis ### Exportar a CSV ```python import csv walls = ifc.by_type("IfcWall") with open("muros.csv", "w", newline="", encoding="utf-8") as f: writer = csv.writer(f) writer.writerow(["GlobalId", "Name", "Tag", "ObjectType"]) for wall in walls: writer.writerow([ wall.GlobalId, wall.Name or "", wall.Tag or "", wall.ObjectType or "" ]) ``` ### Exportar a JSON ```python import json def element_to_dict(el): return { "id": el.GlobalId, "type": el.is_a(), "name": el.Name or "", "properties": get_properties(el), "quantities": get_quantities(el), } data = [element_to_dict(e) for e in ifc.by_type("IfcSpace")] with open("espacios.json", "w", encoding="utf-8") as f: json.dump(data, f, indent=2, ensure_ascii=False) ``` ## Modificar propiedades y guardar IFC ```python import ifcopenshell import ifcopenshell.api ifc = ifcopenshell.open("modelo.ifc") wall = ifc.by_type("IfcWall")[0] # Cambiar el nombre del elemento wall.Name = "Muro Exterior Principal" # Agregar/modificar una propiedad en un PropertySet existente for definition in wall.IsDefinedBy: if definition.is_a("IfcRelDefinesByProperties"): pset = definition.RelatingPropertyDefinition if pset.is_a("IfcPropertySet") and pset.Name == "Pset_WallCommon": for prop in pset.HasProperties: if prop.Name == "IsExternal": prop.NominalValue = ifc.createIfcBoolean(True) # Crear un nuevo PropertySet con ifcopenshell.api pset = ifcopenshell.api.run("pset.add_pset", ifc, product=wall, name="Custom_Props" ) ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={ "EspesorNominal": 0.20, "Acabado": "Pintura blanca", "FechaRevision": "2026-03-01" } ) ifc.write("modelo_modificado.ifc") ``` ## Integración con `llm.generate` para análisis de modelos ```python import json spaces = ifc.by_type("IfcSpace") space_data = [] for space in spaces: props = get_properties(space) quants = get_quantities(space) space_data.append({ "name": space.Name or space.LongName or "Sin nombre", "area_m2": quants.get("NetFloorArea", quants.get("GrossFloorArea", "N/D")), "properties": props }) prompt = f"""Analiza los espacios de este modelo IFC y genera un resumen ejecutivo: - Total de espacios: {len(space_data)} - Datos: {json.dumps(space_data[:20], indent=2, ensure_ascii=False)} Incluye: superficie total, distribución por uso, observaciones sobre normativa.""" # Enviar a Rick para análisis con LLM result = await client.execute_task("llm.generate", { "prompt": prompt, "model": "gemini-2.5-flash" }) ``` ## Integración con `windows.fs.*` para leer IFC desde VM ```python # Leer un IFC almacenado en la VM (G:\Mi unidad\...) result = await client.execute_task("windows.fs.read_binary", { "path": r"G:\Mi unidad\Rick-David\Modelos BIM\edificio.ifc" }) # Guardar localmente, procesar con IfcOpenShell import tempfile, os with tempfile.NamedTemporaryFile(suffix=".ifc", delete=False) as tmp: tmp.write(result["content"]) tmp_path = tmp.name ifc = ifcopenshell.open(tmp_path) # ... procesar ... os.unlink(tmp_path) ``` ## Ejemplo completo: extraer áreas de todos los espacios ```python import ifcopenshell import csv def extract_space_areas(ifc_path: str, output_csv: str): """Extrae GlobalId, nombre, nivel y área de todos los IfcSpace.""" ifc = ifcopenshell.open(ifc_path) spaces = ifc.by_type("IfcSpace") rows = [] for space in spaces: name = space.LongName or space.Name or "Sin nombre" global_id = space.GlobalId level = "N/D" for rel in getattr(space, "ContainedInStructure", []): if rel.RelatingStructure.is_a("IfcBuildingStorey"): level = rel.RelatingStructure.Name break area = None for definition in space.IsDefinedBy: if definition.is_a("IfcRelDefinesByProperties"): qset = definition.RelatingPropertyDefinition if qset.is_a("IfcElementQuantity"): for q in qset.Quantities: if q.is_a("IfcQuantityArea") and "Floor" in q.Name: area = round(q.AreaValue, 2) break rows.append({ "GlobalId": global_id, "Nombre": name, "Nivel": level, "Area_m2": area or "N/D" }) with open(output_csv, "w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=["GlobalId", "Nombre", "Nivel", "Area_m2"]) writer.writeheader() writer.writerows(rows) total = sum(r["Area_m2"] for r in rows if isinstance(r["Area_m2"], (int, float))) print(f"Espacios: {len(rows)} | Superficie total: {total:.2f} m²") return rows # Uso extract_space_areas("edificio.ifc", "espacios_areas.csv") ``` ## Herramientas complementarias ### ifcpatch — Transformaciones batch ```bash ifcpatch -i modelo.ifc -o resultado.ifc -r OffsetObjectPlacement -a 1000,2000,0 ifcpatch -i modelo.ifc -o resultado.ifc -r ResetAbsoluteCoordinates ``` ### ifcdiff — Comparar versiones ```bash ifcdiff modelo_v1.ifc modelo_v2.ifc -o cambios.json ``` ### ifcclash — Detección de interferencias ```python from ifcclash import ifcclash settings = ifcclash.IfcClashSettings() settings.output = "clashes.json" clasher = ifcclash.IfcClash(settings) clasher.add_group("Estructura", "estructura.ifc") clasher.add_group("MEP", "mep.ifc") clasher.clash() clasher.export() ``` ## Ejemplos de uso con Rick - **Rick: "Extraé todas las puertas con sus dimensiones del IFC"** → `by_type("IfcDoor")` + `get_properties()` + exportar a CSV. - **Rick: "Cuántos m² de espacios tiene el modelo?"** → `extract_space_areas()` con sum de áreas. - **Rick: "Compará las dos versiones del modelo IFC"** → `ifcdiff` entre v1 y v2, generar reporte. - **Rick: "Agregá la propiedad 'Zona Sísmica' a todos los muros"** → `ifcopenshell.api.run("pset.edit_pset")` en loop. - **Rick: "Hacé un clash detection entre estructura y MEP"** → `ifcclash` con dos grupos de archivos. ## Recursos oficiales - IfcOpenShell docs: https://ifcopenshell.org/ - IfcOpenShell Python API: https://docs.ifcopenshell.org/ifcopenshell-python/ - buildingSMART IFC spec: https://standards.buildingsmart.org/IFC/ - BlenderBIM (IfcOpenShell GUI): https://blenderbim.org/ - IfcOpenShell GitHub: https://github.com/IfcOpenShell/IfcOpenShell ## Notas - IfcOpenShell es la librería Python de referencia para IFC. Es mantenida por la comunidad y usada en BlenderBIM. - Los archivos IFC son texto plano (STEP/SPF), legibles y versionables con Git. - IFC4 es el schema recomendado para proyectos nuevos; IFC2x3 sigue siendo común en proyectos existentes. - Para geometría 3D (visualización, clash), se necesita el módulo `geometry` que depende de Open CASCADE. - `ifcopenshell.api` provee una API de alto nivel para crear y modificar entidades IFC de forma segura.
عرض على GitHub