Extract structured data from IFC (Industry Foundation Classes) files using IfcOpenShell. Parse BIM models, extract quantities, properties, spatial relationships, and export to various formats.
数据来源:ClawHub。 在 ClawSkills 查看
选择你使用的 Agent
方法一:命令行安装(推荐)
推荐(无需提前安装 clawhub)
npx clawhub@latest --dir ~/.claude/skills install ifc-data-extraction或使用 clawhub CLI(需提前安装)
clawhub --dir ~/.claude/skills install ifc-data-extraction⚠️ 需要 Node.js 18+,没有 Node?请使用下方方法二直接下载 ZIP。 安装 Node.js →
方法二:手动下载安装(无需 Node)
下载 ZIP,解压后将文件夹放到以下路径,重启 Agent 即可:
安装路径
~/.claude/skills/ifc-data-extraction/💡解压后将文件夹放到上方路径,重启 Agent 即可生效
--- name: "ifc-data-extraction" description: "Extract structured data from IFC (Industry Foundation Classes) files using IfcOpenShell. Parse BIM models, extract quantities, properties, spatial relationships, and export to various formats." ---
This skill provides comprehensive IFC file parsing and data extraction using IfcOpenShell. Extract element data, quantities, properties, and relationships from BIM models for analysis and reporting.
Based on Open BIM Standards - Working with vendor-neutral IFC format for maximum interoperability.
> "IFC является открытым стандартом для обмена BIM-данными, позволяющим извлекать информацию независимо от программного обеспечения." > — DDC Methodology
import ifcopenshell
import ifcopenshell.util.element as element_util
import pandas as pd
# Open IFC file
ifc = ifcopenshell.open("model.ifc")
# Get project info
project = ifc.by_type("IfcProject")[0]
print(f"Project: {project.Name}")
# Extract all walls
walls = ifc.by_type("IfcWall")
print(f"Total walls: {len(walls)}")
# Get wall data
wall_data = []
for wall in walls:
psets = element_util.get_psets(wall)
wall_data.append({
'GlobalId': wall.GlobalId,
'Name': wall.Name,
'Type': wall.is_a(),
'Level': get_level(wall),
'Properties': psets
})
df = pd.DataFrame(wall_data)
print(df.head())
import ifcopenshell
import ifcopenshell.util.element as element_util
import ifcopenshell.util.placement as placement_util
import ifcopenshell.geom
import pandas as pd
from typing import List, Dict, Optional, Any
class IFCExtractor:
"""Extract data from IFC files"""
def __init__(self, ifc_path: str):
self.model = ifcopenshell.open(ifc_path)
self.settings = ifcopenshell.geom.settings()
def get_project_info(self) -> Dict:
"""Extract project metadata"""
project = self.model.by_type("IfcProject")[0]
site = self.model.by_type("IfcSite")
building = self.model.by_type("IfcBuilding")
return {
'project_id': project.GlobalId,
'project_name': project.Name,
'description': project.Description,
'site_count': len(site),
'building_count': len(building),
'schema': self.model.schema
}
def get_all_elements(self, element_types: List[str] = None) -> pd.DataFrame:
"""Extract all elements of specified types"""
if element_types is None:
element_types = [
'IfcWall', 'IfcSlab', 'IfcColumn', 'IfcBeam',
'IfcDoor', 'IfcWindow', 'IfcStair', 'IfcRoof'
]
all_elements = []
for ifc_type in element_types:
elements = self.model.by_type(ifc_type)
for elem in elements:
data = self._extract_element_data(elem)
data['IFC_Type'] = ifc_type
all_elements.append(data)
return pd.DataFrame(all_elements)
def _extract_element_data(self, element) -> Dict:
"""Extract data from single element"""
# Basic info
data = {
'GlobalId': element.GlobalId,
'Name': element.Name,
'Description': element.Description,
'ObjectType': element.ObjectType if hasattr(element, 'ObjectType') else None
}
# Get level/storey
data['Level'] = self._get_element_level(element)
# Get material
data['Material'] = self._get_element_material(element)
# Get type
data['TypeName'] = self._get_element_type(element)
# Get all property sets
psets = element_util.get_psets(element)
data['PropertySets'] = psets
# Extract common quantities
base_quantities = psets.get('BaseQuantities', {})
data.update({
'Length': base_quantities.get('Length'),
'Width': base_quantities.get('Width'),
'Height': base_quantities.get('Height'),
'Area': base_quantities.get('NetSideArea') or base_quantities.get('GrossArea'),
'Volume': base_quantities.get('NetVolume') or base_quantities.get('GrossVolume')
})
return data
def _get_element_level(self, element) -> Optional[str]:
"""Get the building storey for an element"""
if hasattr(element, 'ContainedInStructure'):
for rel in element.ContainedInStructure or []:
if rel.RelatingStructure.is_a('IfcBuildingStorey'):
return rel.RelatingStructure.Name
return None
def _get_element_material(self, element) -> Optional[str]:
"""Get material name for element"""
if hasattr(element, 'HasAssociations'):
for rel in element.HasAssociations or []:
if rel.is_a('IfcRelAssociatesMaterial'):
material = rel.RelatingMaterial
if hasattr(material, 'Name'):
return material.Name
elif hasattr(material, 'ForLayerSet'):
layers = material.ForLayerSet.MaterialLayers
if layers:
return layers[0].Material.Name
return None
def _get_element_type(self, element) -> Optional[str]:
"""Get element type name"""
if hasattr(element, 'IsTypedBy'):
for rel in element.IsTypedBy or []:
return rel.RelatingType.Name
return None
def extract_quantities(self) -> pd.DataFrame:
"""Extract quantities for all elements"""
elements = self.get_all_elements()
# Group by category and level
quantities = elements.groupby(['IFC_Type', 'Level']).agg({
'GlobalId': 'count',
'Volume': 'sum',
'Area': 'sum',
'Length': 'sum'
}).rename(columns={'GlobalId': 'Count'}).reset_index()
return quantities
def extract_levels(self) -> pd.DataFrame:
"""Extract building levels/storeys"""
storeys = self.model.by_type("IfcBuildingStorey")
level_data = []
for storey in storeys:
level_data.append({
'GlobalId': storey.GlobalId,
'Name': storey.Name,
'Elevation': storey.Elevation,
'Description': storey.Description
})
return pd.DataFrame(level_data).sort_values('Elevation')
def extract_spaces(self) -> pd.DataFrame:
"""Extract spaces/rooms"""
spaces = self.model.by_type("IfcSpace")
space_data = []
for space in spaces:
psets = element_util.get_psets(space)
base_qty = psets.get('BaseQuantities', {})
space_data.append({
'GlobalId': space.GlobalId,
'Name': space.Name,
'LongName': space.LongName,
'Level': self._get_element_level(space),
'Area': base_qty.get('NetFloorArea'),
'Volume': base_qty.get('NetVolume'),
'Height': base_qty.get('Height')
})
return pd.DataFrame(space_data)
def extract_materials(self) -> pd.DataFrame:
"""Extract material summary"""
materials = {}
for elem in self.model.by_type("IfcProduct"):
material = self._get_element_material(elem)
if material:
if material not in materials:
materials[material] = {'count': 0, 'volume': 0}
materials[material]['count'] += 1
psets = element_util.get_psets(elem)
...安装 Ifc Data Extraction 后,可以对 AI 说这些话来触发它
Help me get started with Ifc Data Extraction
Explains what Ifc Data Extraction does, walks through the setup, and runs a quick demo based on your current project
Use Ifc Data Extraction to extract structured data from IFC (Industry Foundation Classes) file...
Invokes Ifc Data Extraction with the right parameters and returns the result directly in the conversation
What can I do with Ifc Data Extraction in my developer & devops workflow?
Lists the top use cases for Ifc Data Extraction, with example commands for each scenario
将技能文件夹放到 ~/.claude/skills/ifc-data-extraction/ 目录(个人级,所有项目可用),或 .claude/skills/ifc-data-extraction/(项目级)。重启 AI 客户端后,用 /ifc-data-extraction 主动调用,或让 AI 根据上下文自动发现并使用。
Ifc Data Extraction 支持 Claude、Cursor、OpenClaw,可与这些 AI 平台无缝集成,扩展其能力。
Ifc Data Extraction 可免费安装使用。请查阅仓库了解许可证信息。
Extract structured data from IFC (Industry Foundation Classes) files using IfcOpenShell. Parse BIM models, extract quantities, properties, spatial relationships, and export to various formats.
Ifc Data Extraction 属于「Developer & DevOps」分类,该分类的技能帮助 AI 智能体在此领域执行专业任务。
Automate my developer & devops tasks using Ifc Data Extraction
Identifies repetitive steps in your workflow and sets up Ifc Data Extraction to handle them automatically