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
최근 소스 활동
2026년 3월 4일 23:53
감지된 SKILL.md 언어
스페인어
스타
0
포크
0

설치 방법

기본적으로 소스를 먼저 확인하는 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에서 보기