# Crosstech Impl Freecad Ifc Bridge

> >

- **Type:** Skill
- **Install:** `agentstack add skill-impertio-studio-cross-tech-aec-claude-skill-package-crosstech-impl-freecad-ifc-bridge`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Impertio-Studio](https://agentstack.voostack.com/s/impertio-studio)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Impertio-Studio](https://github.com/Impertio-Studio)
- **Source:** https://github.com/Impertio-Studio/Cross-Tech-AEC-Claude-Skill-Package/tree/main/skills/source/crosstech-impl/crosstech-impl-freecad-ifc-bridge

## Install

```sh
agentstack add skill-impertio-studio-cross-tech-aec-claude-skill-package-crosstech-impl-freecad-ifc-bridge
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# crosstech-impl-freecad-ifc-bridge

## Quick Reference

### FreeCAD IFC Modes

| Mode | FreeCAD Version | IFC Engine | Data Loss | Round-Trip |
|------|----------------|------------|-----------|------------|
| NativeIFC Locked | 1.0+ | IfcOpenShell 0.8.x | NONE | Lossless |
| NativeIFC Unlocked | 1.0+ | IfcOpenShell 0.8.x | NONE (IFC part) | Lossless |
| Legacy Import/Export |  `IfcSite` > `IfcBuilding` > `IfcBuildingStorey`

**Data model**:
- Entities inherit from `IfcRoot` (GlobalId, Name, Description, OwnerHistory)
- Relationships are objectified (`IfcRelAggregates`, `IfcRelContainedInSpatialStructure`)
- Types shared via `IfcRelDefinesByType`
- Materials assigned via `IfcRelAssociatesMaterial`

### The Bridge: NativeIFC / Traditional Import-Export

**NativeIFC (PREFERRED)**: The IFC file IS the FreeCAD document. No conversion happens. IfcOpenShell reads and writes IFC data directly. FreeCAD renders shapes on demand using IfcOpenShell's OpenCASCADE geometry converter.

**Traditional Import**: IfcOpenShell parses IFC geometry and converts it to FreeCAD `Part::TopoShape` objects. This is a one-way conversion that loses IFC semantic data unless explicitly mapped to FreeCAD properties.

**Traditional Export**: FreeCAD BIM objects are serialized to IFC entities using IfcOpenShell. BIM type mappings (`Arch.Wall` -> `IfcWall`) are applied automatically. Non-BIM objects are excluded unless explicitly converted.

**Data flow**:
```
NativeIFC:     IFC file  FreeCAD viewport (via IfcOpenShell)
Traditional:   IFC file --> IfcOpenShell --> Part::TopoShape --> FreeCAD
               FreeCAD --> Arch/BIM objects --> IfcOpenShell --> IFC file
```

---

## Critical Rules

1. **ALWAYS** prefer NativeIFC mode over legacy import/export for IFC workflows.
2. **ALWAYS** check IfcOpenShell availability before IFC operations: `import ifcopenshell`.
3. **ALWAYS** use locked NativeIFC mode when the IFC file is the single source of truth.
4. **ALWAYS** use unlocked NativeIFC mode when mixing IFC with non-IFC elements.
5. **ALWAYS** load shapes selectively for large models — NativeIFC supports on-demand loading.
6. **ALWAYS** verify schema version with `ifcopenshell.open(path).schema` before processing.
7. **NEVER** assume FreeCAD preserves IFC parametric geometry in legacy mode — it converts to BREP.
8. **NEVER** edit IFC files outside FreeCAD while they are open in NativeIFC locked mode.
9. **NEVER** rely on FreeCAD-specific parametric constraints surviving IFC export — Sketcher constraints and Part constraints are NOT part of IFC.
10. **NEVER** use `importIFC.export()` for NativeIFC workflows — save the document directly.

---

## Decision Tree

```
START: You need to work with IFC in FreeCAD
|
+-- Q1: Is FreeCAD 1.0+ available?
|   +-- YES --> Use BIM Workbench with NativeIFC
|   +-- NO  --> Use legacy Arch import/export (expect data loss)
|
+-- Q2: What is the workflow?
|   +-- View/inspect IFC --> NativeIFC locked mode (read-only is fine)
|   +-- Edit IFC and save back --> NativeIFC locked mode
|   +-- Combine IFC with non-IFC geometry --> NativeIFC unlocked mode
|   +-- Create BIM model from scratch --> BIM Workbench, export to IFC
|   +-- One-time geometry extraction --> Legacy import is acceptable
|
+-- Q3: Is the IFC file large (>100MB)?
|   +-- YES --> Use NativeIFC with selective shape loading
|   +-- NO  --> Full shape loading is acceptable
|
+-- Q4: Is round-trip fidelity required?
|   +-- YES --> NativeIFC locked mode ONLY
|   +-- NO  --> Legacy export is acceptable for one-way conversion
|
+-- Q5: Do you need scripting access to IFC data?
    +-- YES, to IFC entities --> Use ifcopenshell directly on the file
    +-- YES, to FreeCAD objects --> Use FreeCAD.ActiveDocument.Objects
    +-- YES, to both --> NativeIFC mode (objects ARE IFC entities)
```

---

## Essential Patterns

### Pattern 1: Open IFC in NativeIFC Locked Mode

```python
import FreeCAD

# Open IFC file directly — NativeIFC treats it as the document
doc = FreeCAD.openDocument("/path/to/model.ifc")

# Iterate IFC objects
for obj in doc.Objects:
    if hasattr(obj, "IfcType"):
        print(f"{obj.Label}: {obj.IfcType}")

# Modify an element
wall = doc.getObjectsByLabel("Exterior Wall 01")[0]
wall.Label = "Renamed Wall"

# Save — writes directly to the IFC file, minimal diff
doc.save()
```

### Pattern 2: Access IFC Data via IfcOpenShell (NativeIFC)

```python
import FreeCAD
import ifcopenshell
import ifcopenshell.util.element

# Open the IFC file with IfcOpenShell for semantic queries
ifc_file = ifcopenshell.open("/path/to/model.ifc")

# Query all walls with their properties
for wall in ifc_file.by_type("IfcWall"):
    psets = ifcopenshell.util.element.get_psets(wall)
    name = wall.Name or "Unnamed"
    is_external = psets.get("Pset_WallCommon", {}).get("IsExternal", None)
    print(f"{name}: external={is_external}")

# Check schema version
print(f"Schema: {ifc_file.schema}")  # "IFC2X3", "IFC4", "IFC4X3"
```

### Pattern 3: Create BIM Objects and Export to IFC

```python
import FreeCAD
import Arch
import Draft

# Create a new document
doc = FreeCAD.newDocument("BIM_Project")

# Create BIM objects using the Arch module
wall = Arch.makeWall(length=5000, width=200, height=3000)
wall.IfcType = "IfcWall"
wall.Label = "Exterior Wall 01"

# Create a slab
slab = Arch.makeStructure(length=6000, width=5000, height=200)
slab.IfcType = "IfcSlab"
slab.Label = "Ground Floor Slab"

# Recompute to update geometry
doc.recompute()

# Export to IFC using the legacy exporter
import importIFC
importIFC.export([wall, slab], "/path/to/output.ifc")
```

### Pattern 4: NativeIFC Unlocked Mode (Mixed Content)

```python
import FreeCAD
import Arch

# Create document with mixed content
doc = FreeCAD.newDocument("Mixed_Project")

# Add non-IFC geometry (parametric FreeCAD part)
import Part
box = doc.addObject("Part::Box", "SiteContext")
box.Length = 10000
box.Width = 10000
box.Height = 100

# Add IFC project (unlocked mode — IFC and non-IFC coexist)
# The IFC project attaches to a separate .ifc file
# Non-IFC objects (like the box) remain in the .FCStd file

doc.recompute()
```

### Pattern 5: Selective Shape Loading for Large Models

```python
import FreeCAD

# Open large IFC file — NativeIFC loads metadata only
doc = FreeCAD.openDocument("/path/to/large_model.ifc")

# Shapes are loaded on demand per object
# Access an object to trigger shape loading
obj = doc.getObjectsByLabel("Foundation Wall")[0]
shape = obj.Shape  # Triggers geometry computation via IfcOpenShell

# For batch processing without visualization, avoid loading shapes
for obj in doc.Objects:
    if hasattr(obj, "IfcType"):
        # Access metadata only — no shape loading
        print(f"{obj.Label}: {obj.IfcType}")
```

---

## Common Operations

### Import/Export Operations

| Operation | NativeIFC (Preferred) | Legacy |
|-----------|----------------------|--------|
| Open IFC | `FreeCAD.openDocument("f.ifc")` | File > Import > IFC |
| Save IFC | `doc.save()` (writes to .ifc) | `importIFC.export(objs, "f.ifc")` |
| Access properties | Via IfcOpenShell on same file | Custom properties on FreeCAD object |
| Round-trip edit | Direct — changes write to IFC | Lossy — re-export required |
| Large file handling | Selective shape loading | Full load into memory |

### FreeCAD BIM Type Mapping

| FreeCAD BIM Object | IFC Entity | Notes |
|-------------------|------------|-------|
| `Arch.makeWall()` | `IfcWall` | Maps directly |
| `Arch.makeStructure()` | `IfcColumn` / `IfcBeam` / `IfcSlab` | Based on IfcType property |
| `Arch.makeWindow()` | `IfcWindow` / `IfcDoor` | Based on IfcType property |
| `Arch.makeStairs()` | `IfcStair` | Maps directly |
| `Arch.makeRoof()` | `IfcRoof` | Maps directly |
| `Arch.makePipe()` | `IfcPipeSegment` | Maps directly |
| `Arch.makeSite()` | `IfcSite` | Spatial element |
| `Arch.makeBuilding()` | `IfcBuilding` | Spatial element |
| `Arch.makeFloor()` | `IfcBuildingStorey` | Spatial element |

### Data Preservation Matrix

| Data Type | NativeIFC | Legacy Import | Legacy Export |
|-----------|:---------:|:------------:|:------------:|
| IFC entity class | FULL | FULL | FULL |
| GlobalId | FULL | Stored as property | Generated new |
| Property sets | FULL | Partial (custom props) | Partial |
| Quantities | FULL | Partial | Partial |
| Relationships | FULL | Simplified | Simplified |
| Parametric geometry | FULL | Converted to BREP | From BREP |
| Material layers | FULL | Simplified | Simplified |
| Spatial hierarchy | FULL | Collection hierarchy | Regenerated |
| FreeCAD constraints | N/A | N/A | **LOST** |
| Sketcher data | N/A | N/A | **LOST** |

### Scripting Quick Reference

```python
# Check FreeCAD version
import FreeCAD
print(FreeCAD.Version())  # ['1', '0', '0', ...]

# Check IfcOpenShell version
import ifcopenshell
print(ifcopenshell.version)  # "0.8.0" or similar

# Check if NativeIFC is available
try:
    import nativeifc
    NATIVEIFC_AVAILABLE = True
except ImportError:
    NATIVEIFC_AVAILABLE = False

# Get all IFC objects in current document
doc = FreeCAD.ActiveDocument
ifc_objects = [o for o in doc.Objects if hasattr(o, "IfcType")]

# Access underlying IfcOpenShell entity (NativeIFC)
import ifcopenshell
ifc_file = ifcopenshell.open(doc.FileName)
entity = ifc_file.by_id(42)  # Access by expressID
```

---

## Reference Links

- [references/methods.md](references/methods.md) -- FreeCAD BIM/Arch API and IfcOpenShell within FreeCAD
- [references/examples.md](references/examples.md) -- Import/export/round-trip workflow examples
- [references/anti-patterns.md](references/anti-patterns.md) -- FreeCAD IFC mistakes and data loss patterns

### Official Sources

- https://wiki.freecad.org/BIM_Workbench -- FreeCAD BIM Workbench documentation
- https://wiki.freecad.org/NativeIFC -- NativeIFC mode documentation
- https://github.com/yorikvanhavre/FreeCAD-NativeIFC -- NativeIFC source code
- https://docs.ifcopenshell.org/ -- IfcOpenShell 0.8.x API documentation
- https://wiki.freecad.org/Arch_IFC -- Legacy Arch IFC import/export
- https://wiki.freecad.org/Manual:BIM_modeling -- FreeCAD BIM modeling manual

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Impertio-Studio](https://github.com/Impertio-Studio)
- **Source:** [Impertio-Studio/Cross-Tech-AEC-Claude-Skill-Package](https://github.com/Impertio-Studio/Cross-Tech-AEC-Claude-Skill-Package)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** yes
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-impertio-studio-cross-tech-aec-claude-skill-package-crosstech-impl-freecad-ifc-bridge
- Seller: https://agentstack.voostack.com/s/impertio-studio
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
