Create 4D construction simulations by linking BIM elements to project schedules. Generate time-based visualizations, sequence analysis, and construction phasing with Gantt integration.
日本語の概要は準備中です。原文の説明を表示しています。
Convert IFC files (2x3, 4x1, 4x3) to Excel databases using IfcExporter CLI. Extract BIM data, properties, and geometry without proprietary software.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
IFC (Industry Foundation Classes) is the open BIM standard, but:
IfcExporter.exe converts IFC files to structured Excel databases, making BIM data accessible for analysis, validation, and reporting.
IfcExporter.exe <input_ifc> [options]
| Version | Schema | Description |
|---|---|---|
| IFC2x3 | MVD | Most common exchange format |
| IFC4 | ADD1 | Enhanced properties |
| IFC4x1 | Alignment | Infrastructure support |
| IFC4x3 | Latest | Full infrastructure |
| Output | Description |
|---|---|
.xlsx | Excel database with elements and properties |
.dae | Collada 3D geometry with matching IDs |
| Option | Description |
|---|---|
bbox | Include element bounding boxes |
-no-xlsx | Skip Excel export |
-no-collada | Skip 3D geometry export |
# Basic conversion (XLSX + DAE)
IfcExporter.exe "C:\Models\Building.ifc"
# With bounding boxes
IfcExporter.exe "C:\Models\Building.ifc" bbox
# Excel only (no 3D geometry)
IfcExporter.exe "C:\Models\Building.ifc" -no-collada
# Batch processing
for /R "C:\IFC_Models" %f in (*.ifc) do IfcExporter.exe "%f" bbox
import subprocess
import pandas as pd
from pathlib import Path
from typing import List, Optional, Dict, Any, Set
from dataclasses import dataclass, field
from enum import Enum
import json
class IFCVersion(Enum):
"""IFC schema versions."""
IFC2X3 = "IFC2X3"
IFC4 = "IFC4"
IFC4X1 = "IFC4X1"
IFC4X3 = "IFC4X3"
class IFCEntityType(Enum):
"""Common IFC entity types."""
IFCWALL = "IfcWall"
IFCWALLSTANDARDCASE = "IfcWallStandardCase"
IFCSLAB = "IfcSlab"
IFCCOLUMN = "IfcColumn"
IFCBEAM = "IfcBeam"
IFCDOOR = "IfcDoor"
IFCWINDOW = "IfcWindow"
IFCROOF = "IfcRoof"
IFCSTAIR = "IfcStair"
IFCRAILING = "IfcRailing"
IFCFURNISHINGELEMENT = "IfcFurnishingElement"
IFCSPACE = "IfcSpace"
IFCBUILDINGSTOREY = "IfcBuildingStorey"
IFCBUILDING = "IfcBuilding"
IFCSITE = "IfcSite"
@dataclass
class IFCElement:
"""Represents an IFC element."""
global_id: str
ifc_type: str
name: str
description: Optional[str]
object_type: Optional[str]
level: Optional[str]
# Quantities
area: Optional[float] = None
volume: Optional[float] = None
length: Optional[float] = None
height: Optional[float] = None
width: Optional[float] = None
# Bounding box (if exported)
bbox_min_x: Optional[float] = None
bbox_min_y: Optional[float] = None
bbox_min_z: Optional[float] = None
bbox_max_x: Optional[float] = None
bbox_max_y: Optional[float] = None
bbox_max_z: Optional[float] = None
# Properties
properties: Dict[str, Any] = field(default_factory=dict)
materials: List[str] = field(default_factory=list)
@dataclass
class IFCProperty:
"""Represents an IFC property."""
pset_name: str
property_name: str
value: Any
value_type: str
@dataclass
class IFCMaterial:
"""Represents an IFC material."""
name: str
category: Optional[str]
thickness: Optional[float]
layer_position: Optional[int]
class IFCExporter:
"""IFC to Excel converter using DDC IfcExporter CLI."""
def __init__(self, exporter_path: str = "IfcExporter.exe"):
self.exporter = Path(exporter_path)
if not self.exporter.exists():
raise FileNotFoundError(f"IfcExporter not found: {exporter_path}")
def convert(self, ifc_file: str,
include_bbox: bool = True,
export_xlsx: bool = True,
export_collada: bool = True) -> Path:
"""Convert IFC file to Excel."""
ifc_path = Path(ifc_file)
if not ifc_path.exists():
raise FileNotFoundError(f"IFC file not found: {ifc_file}")
cmd = [str(self.exporter), str(ifc_path)]
if include_bbox:
cmd.append("bbox")
if not export_xlsx:
cmd.append("-no-xlsx")
if not export_collada:
cmd.append("-no-collada")
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(f"Export failed: {result.stderr}")
return ifc_path.with_suffix('.xlsx')
def batch_convert(self, folder: str,
include_subfolders: bool = True,
include_bbox: bool = True) -> List[Dict[str, Any]]:
"""Convert all IFC files in folder."""
folder_path = Path(folder)
pattern = "**/*.ifc" if include_subfolders else "*.ifc"
results = []
for ifc_file in folder_path.glob(pattern):
try:
output = self.convert(str(ifc_file), include_bbox)
results.append({
'input': str(ifc_file),
'output': str(output),
'status': 'success'
})
print(f"✓ Converted: {ifc_file.name}")
except Exception as e:
results.append({
'input': str(ifc_file),
'output': None,
'status': 'failed',
'error': str(e)
})
print(f"✗ Failed: {ifc_file.name} - {e}")
return results
def read_elements(self, xlsx_file: str) -> pd.DataFrame:
"""Read converted Excel as DataFrame."""
return pd.read_excel(xlsx_file, sheet_name="Elements")
def get_element_types(self, xlsx_file: str) -> pd.DataFrame:
"""Get element type summary."""
df = self.read_elements(xlsx_file)
if 'IfcType' not in df.columns:
raise ValueError("IfcType column not found")
summary = df.groupby('IfcType').agg({
'GlobalId': 'count',
'Volume': 'sum' if 'Volume' in df.columns else 'count',
'Area': 'sum' if 'Area' in df.columns else 'count'
}).reset_index()
summary.columns = ['IFC_Type', 'Count', 'Total_Volume', 'Total_Area']
return summary.sort_values('Count', ascending=False)
def get_levels(self, xlsx_file: str) -> pd.DataFrame:
"""Get building level summary."""
df = self.read_elements(xlsx_file)
level_col = None
for col in ['Level', 'BuildingStorey', 'IfcBuildingStorey']:
if col in df.columns:
level_col = col
break
if level_col is None:
return pd.DataFrame(columns=['Level', 'Element_Count'])
summary = df.groupby(level_col).agg({
'GlobalId': 'count'
}).reset_index()
summary.columns = ['Level', 'Element_Count']
return summary
def get_materials(self, xlsx_file: str) -> pd.DataFrame:
"""Get material summary."""
df = self.read_elements(xlsx_file)
if 'Material' not in df.columns:
return pd.DataFrame(columns=['Material', 'Count'])
summary = df.groupby('Material').agg({
'GlobalId': 'count'
}).reset_index()
summary.columns = ['Material', 'Element_Count']
return summary.sort_values('Element_Count', ascending=False)
def get_quantities(self, xlsx_file: str,
group_by: str = 'IfcType') -> pd.DataFrame:
"""Get quantity takeoff summary."""
df = self.read_elements(xlsx_file)
if group_by not in df.columns:
raise ValueError(f"Column {group_by} not found")
agg_dict = {'GlobalId': 'count'}
# Add numeric columns for aggregation
numeric_cols = ['Volume', 'Area', 'Length', 'Width', 'Height']
for col in numeric_cols:
if col in df.columns:
agg_dict[col] = 'sum'
summary = df.groupby(group_by).agg(agg_dict).reset_index()
return summary
def filter_by_type(self, xlsx_file: str,
ifc_types: List[str]) -> pd.DataFrame:
"""Filter elements by IFC type."""
df = self.read_elements(xlsx_file)
return df[df['IfcType'].isin(ifc_types)]
def get_properties(self, xlsx_file: str,
element_id: str) -> Dict[str, Any]:
"""Get all properties for specific element."""
df = self.read_elements(xlsx_file)
element = df[df['GlobalId'] == element_id]
if element.empty:
return {}
# Convert row to dictionary, excluding NaN values
props = element.iloc[0].dropna().to_dict()
return props
def validate_ifc_data(self, xlsx_file: str) -> Dict[str, Any]:
"""Validate IFC data quality."""
df = self.read_elements(xlsx_file)
validation = {
'total_elements': len(df),
'issues': []
}
# Check for missing GlobalIds
if 'GlobalId' in df.columns:
missing_ids = df['GlobalId'].isna().sum()
if missing_ids > 0:
validation['issues'].append(f"{missing_ids} elements missing GlobalId")
# Check for missing names
if 'Name' in df.columns:
missing_names = df['Name'].isna().sum()
if missing_names > 0:
validation['issues'].append(f"{missing_names} elements missing Name")
# Check for zero quantities
for col in ['Volume', 'Area']:
if col in df.columns:
zero_qty = (df[col] == 0).sum()
if zero_qty > 0:
validation['issues'].append(f"{zero_qty} elements with zero {col}")
# Check for duplicate GlobalIds
if 'GlobalId' in df.columns:
duplicates = df['GlobalId'].duplicated().sum()
if duplicates > 0:
validation['issues'].append(f"{duplicates} duplicate GlobalIds")
validation['is_valid'] = len(validation['issues']) == 0
return validation
class IFCQuantityTakeoff:
"""Quantity takeoff from IFC data."""
def __init__(self, exporter: IFCExporter):
self.exporter = exporter
def generate_qto(self, ifc_file: str) -> Dict[str, pd.DataFrame]:
"""Generate complete quantity takeoff."""
xlsx = self.exporter.convert(ifc_file, include_bbox=True)
df = self.exporter.read_elements(str(xlsx))
qto = {}
# Walls
walls = df[df['IfcType'].str.contains('Wall', case=False, na=False)]
if not walls.empty:
qto['Walls'] = self._summarize_elements(walls, 'Type Name')
# Slabs
slabs = df[df['IfcType'].str.contains('Slab', case=False, na=False)]
if not slabs.empty:
qto['Slabs'] = self._summarize_elements(slabs, 'Type Name')
# Columns
columns = df[df['IfcType'].str.contains('Column', case=False, na=False)]
if not columns.empty:
qto['Columns'] = self._summarize_elements(columns, 'Type Name')
# Beams
beams = df[df['IfcType'].str.contains('Beam', case=False, na=False)]
if not beams.empty:
qto['Beams'] = self._summarize_elements(beams, 'Type Name')
# Doors
doors = df[df['IfcType'].str.contains('Door', case=False, na=False)]
if not doors.empty:
qto['Doors'] = self._summarize_elements(doors, 'Type Name')
# Windows
windows = df[df['IfcType'].str.contains('Window', case=False, na=False)]
if not windows.empty:
qto['Windows'] = self._summarize_elements(windows, 'Type Name')
return qto
def _summarize_elements(self, df: pd.DataFrame,
group_col: str) -> pd.DataFrame:
"""Summarize elements by grouping column."""
if group_col not in df.columns:
group_col = 'IfcType'
agg_dict = {'GlobalId': 'count'}
for col in ['Volume', 'Area', 'Length']:
if col in df.columns:
agg_dict[col] = 'sum'
summary = df.groupby(group_col).agg(agg_dict).reset_index()
summary.rename(columns={'GlobalId': 'Count'}, inplace=True)
return summary
def export_to_excel(self, qto: Dict[str, pd.DataFrame],
output_file: str):
"""Export QTO to multi-sheet Excel."""
with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
for sheet_name, df in qto.items():
df.to_excel(writer, sheet_name=sheet_name, index=False)
# Convenience functions
def convert_ifc_to_excel(ifc_file: str,
exporter_path: str = "IfcExporter.exe") -> str:
"""Quick conversion of IFC to Excel."""
exporter = IFCExporter(exporter_path)
output = exporter.convert(ifc_file)
return str(output)
def get_ifc_summary(xlsx_file: str) -> Dict[str, Any]:
"""Get summary of converted IFC data."""
df = pd.read_excel(xlsx_file, sheet_name="Elements")
return {
'total_elements': len(df),
'ifc_types': df['IfcType'].nunique() if 'IfcType' in df.columns else 0,
'levels': df['Level'].nunique() if 'Level' in df.columns else 0,
'total_volume': df['Volume'].sum() if 'Volume' in df.columns else 0,
'total_area': df['Area'].sum() if 'Area' in df.columns else 0
}
| Sheet | Content |
|---|---|
| Elements | All IFC elements with properties |
| Types | Element types summary |
| Levels | Building storey data |
| Materials | Material assignments |
| PropertySets | IFC property sets |
| Column | Type | Description |
|---|---|---|
| GlobalId | string | IFC GUID |
| IfcType | string | IFC entity type |
| Name | string | Element name |
| Description | string | Element description |
| Level | string | Building storey |
| Material | string | Primary material |
| Volume | float | Volume (m³) |
| Area | float | Surface area (m²) |
| Length | float | Length (m) |
| Height | float | Height (m) |
| Width | float | Width (m) |
# Initialize exporter
exporter = IFCExporter("C:/DDC/IfcExporter.exe")
# Convert IFC to Excel
xlsx = exporter.convert("C:/Models/Building.ifc", include_bbox=True)
# Read elements
df = exporter.read_elements(str(xlsx))
print(f"Total elements: {len(df)}")
# Get element types
types = exporter.get_element_types(str(xlsx))
print(types)
# Get quantities by type
qto = exporter.get_quantities(str(xlsx), group_by='IfcType')
print(qto)
exporter = IFCExporter()
xlsx = exporter.convert("model.ifc")
validation = exporter.validate_ifc_data(str(xlsx))
if not validation['is_valid']:
print("Issues found:")
for issue in validation['issues']:
print(f" - {issue}")
qto_generator = IFCQuantityTakeoff(exporter)
qto = qto_generator.generate_qto("building.ifc")
for category, data in qto.items():
print(f"\n{category}:")
print(data.to_string(index=False))
xlsx = exporter.convert("building.ifc")
materials = exporter.get_materials(str(xlsx))
print(materials)
# Full pipeline: IFC → Excel → Validation → Cost Estimate
exporter = IFCExporter("C:/DDC/IfcExporter.exe")
# 1. Convert IFC
xlsx = exporter.convert("project.ifc", include_bbox=True)
# 2. Validate data
validation = exporter.validate_ifc_data(str(xlsx))
print(f"Valid: {validation['is_valid']}")
# 3. Generate QTO
qto = IFCQuantityTakeoff(exporter)
quantities = qto.generate_qto("project.ifc")
# 4. Export for cost estimation
qto.export_to_excel(quantities, "project_qto.xlsx")
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Create 4D construction simulations by linking BIM elements to project schedules. Generate time-based visualizations, sequence analysis, and construction phasing with Gantt integration.
日本語の概要は準備中です。原文の説明を表示しています。
Analyze 5000+ IFC and Revit projects at scale for patterns, benchmarks, and insights. Big data analysis for construction.
日本語の概要は準備中です。原文の説明を表示しています。
Check construction AI systems against the EU AI Act (Regulation 2024/1689): classify risk of estimation, scheduling, CV and agent tools, document transparency, keep human oversight. Use when deploying or auditing AI in construction.
日本語の概要は準備中です。原文の説明を表示しています。
Orchestrate multiple AI agents for construction workflows: estimator, scheduler, document, QA and safety agents coordinated by a supervisor agent, with human checkpoints. Use when automating end-to-end project processes with agentic AI.
日本語の概要は準備中です。原文の説明を表示しています。
Create Apache Airflow DAGs for construction data pipelines. Orchestrate ETL, validation, and reporting workflows.
日本語の概要は準備中です。原文の説明を表示しています。
Automate as-built documentation and digital handover for construction. Compile project records, generate O&M manuals, create asset databases, and ensure complete project closeout.
日本語の概要は準備中です。原文の説明を表示しています。