Use when assigning materials to IFC elements -- single materials, layer sets (walls), profile sets (beams/columns), or constituent sets (IFC4+). Prevents the common mistake of using IfcMaterialConstituentSet in IFC2X3 (not available). Covers IfcMaterial, IfcMaterialLayerSet, IfcMaterialProfileSet, material properties, and presentation. Keywords: material, IfcMaterial, layer set, profile set, constituent set, material assignment, IfcMaterialLayerSet, IfcMaterialProfileSet, material properties, assign material, wall layers.
Use when assigning materials to IFC elements -- single materials, layer sets (walls), profile sets (beams/columns), or constituent sets (IFC4+). Prevents the common mistake of using IfcMaterialConstituentSet in IFC2X3 (not available). Covers IfcMaterial, IfcMaterialLayerSet, IfcMaterialProfileSet, material properties, and presentation. Keywords: material, IfcMaterial, layer set, profile set, constituent set, material assignment, IfcMaterialLayerSet, IfcMaterialProfileSet, material properties, assign material, wall layers.
license
MIT
compatibility
Designed for Claude Code. Requires IfcOpenShell Python library.
metadata
{"author":"OpenAEC-Foundation","version":"1.0"}
IFC Material Assignment Implementation Guide
Quick Reference
Decision Tree: Which Material Type to Use
What kind of element needs material?
├── Single homogeneous material (e.g., steel column, concrete beam)?
│ └── IfcMaterial → assign_material(type="IfcMaterial")
│
├── Layered construction (wall, slab, roof with defined layers)?
│ └── IfcMaterialLayerSet → add_material_set(set_type="IfcMaterialLayerSet")
│ └── Each layer has a thickness (LayerThickness in meters)
│
├── Profiled structural element (beam, column with cross-section)?
│ └── IfcMaterialProfileSet → add_material_set(set_type="IfcMaterialProfileSet")
│ └── Each profile has an IfcProfileDef defining the cross-section
│
├── Composite element with named parts (window: frame+glazing)?
│ ├── IFC4+ → IfcMaterialConstituentSet
│ │ └── add_material_set(set_type="IfcMaterialConstituentSet")
│ └── IFC2X3 → IfcMaterialList (legacy, no named parts)
│ └── add_material_set(set_type="IfcMaterialList")
│
└── Legacy unordered material list (IFC2X3 only)?
└── IfcMaterialList → add_material_set(set_type="IfcMaterialList")
Decision Tree: Assign Material to Type or Occurrence?
Where to assign the material?
├── Element type (IfcWallType, IfcSlabType, etc.)? [RECOMMENDED]
│ └── Assign to type → all occurrences inherit the material
│ └── ifcopenshell.api.material.assign_material(model,
│ products=[wall_type], type="IfcMaterialLayerSet", material=layer_set)
│
└── Individual occurrence (IfcWall, IfcSlab, etc.)?
└── Assign to occurrence → overrides type material for this element only
└── ifcopenshell.api.material.assign_material(model,
products=[wall], material=concrete)
Critical Warnings
ALWAYS assign materials to element types (IfcWallType, IfcSlabType), not individual occurrences. Occurrences inherit from their type. Assign to occurrences only when overriding type material.
ALWAYS use ifcopenshell.api.material.* functions for material operations. NEVER create IfcMaterial or IfcRelAssociatesMaterial entities directly with create_entity().
NEVER use IfcMaterialConstituentSet with IFC2X3 schema. It does not exist in IFC2X3. Use IfcMaterialList instead.
ALWAYS check model.schema before using schema-specific material types.
NEVER assign multiple materials directly to the same product. Use material sets (layer, profile, constituent) for composite materials. assign_material() automatically unassigns previous materials.
ALWAYS set LayerThickness on layers after creation using edit_layer(). Layers without thickness are invalid.
ALWAYS provide a profile definition (IfcProfileDef) when adding profiles to a profile set. A material profile without a profile curve is incomplete.
NEVER set material relationships via direct attribute assignment (e.g., wall.HasAssociations = ...). ALWAYS use the API.
Essential Patterns
Pattern 1: Create and Assign a Single Material
# IfcOpenShell: all schema versionsimport ifcopenshell
import ifcopenshell.api
# Create a material with category
concrete = ifcopenshell.api.material.add_material(model,
name="Concrete C30/37", category="concrete")
# Assign to a wall (single material, no layers)
ifcopenshell.api.material.assign_material(model,
products=[wall], material=concrete)
Pattern 2: Create a Layered Wall Material (IfcMaterialLayerSet)
# IfcOpenShell: all schema versionsimport ifcopenshell.util.element
# Get material (returns IfcMaterial, IfcMaterialLayerSet, etc.)
material = ifcopenshell.util.element.get_material(wall)
if material isNone:
print("No material assigned")
elif material.is_a("IfcMaterial"):
print(f"Single material: {material.Name}")
elif material.is_a("IfcMaterialLayerSet"):
for layer in material.MaterialLayers:
print(f"Layer: {layer.Material.Name}, Thickness: {layer.LayerThickness}")
elif material.is_a("IfcMaterialLayerSetUsage"):
layer_set = material.ForLayerSet
for layer in layer_set.MaterialLayers:
print(f"Layer: {layer.Material.Name}, Thickness: {layer.LayerThickness}")
elif material.is_a("IfcMaterialProfileSet"):
for profile in material.MaterialProfiles:
print(f"Profile: {profile.Material.Name}")
elif material.is_a("IfcMaterialConstituentSet"):
for constituent in material.MaterialConstituents:
print(f"Constituent: {constituent.Name} - {constituent.Material.Name}")
# IfcOpenShell: all schema versions
ifcopenshell.api.material.unassign_material(model, products=[wall])
Copy a Material with All Properties
# IfcOpenShell: all schema versions
new_material = ifcopenshell.api.material.copy_material(model,
material=existing_material)
# Copies psets and styles. Set items are copied but underlying materials reused.
# IfcOpenShell: all schema versions
ifcopenshell.api.material.reorder_set_item(model,
material_set=layer_set, old_index=2, new_index=0)
Edit Layer Usage (Offset from Reference Line)
# IfcOpenShell: all schema versions# Get the usage from the element
material = ifcopenshell.util.element.get_material(wall)
if material.is_a("IfcMaterialLayerSetUsage"):
ifcopenshell.api.material.edit_layer_usage(model,
usage=material, attributes={"OffsetFromReferenceLine": -0.1})
Delete Material and Material Set
# IfcOpenShell: all schema versions# First unassign from all products
ifcopenshell.api.material.unassign_material(model, products=[wall_type])
# Then remove the material set
ifcopenshell.api.material.remove_material_set(model, material_set=layer_set)
# Remove individual materials (only if not used elsewhere)
ifcopenshell.api.material.remove_material(model, material=brick)
Version Notes
IFC2X3 vs IFC4+ Material Differences
Feature
IFC2X3
IFC4 / IFC4X3
IfcMaterial
Yes
Yes
IfcMaterialLayerSet
Yes
Yes
IfcMaterialProfileSet
Yes
Yes
IfcMaterialConstituentSet
No
Yes
IfcMaterialList
Yes (primary)
Yes (legacy)
Material category attribute
No
Yes
Material description attribute
No
Yes
Schema-Aware Material Assignment
# IfcOpenShell: all schema versionsimport ifcopenshell.util.element
if model.schema == "IFC2X3":
# IFC2X3: Use IfcMaterialList for composite elements
material_list = ifcopenshell.api.material.add_material_set(model,
name="Window Materials", set_type="IfcMaterialList")
ifcopenshell.api.material.add_list_item(model,
material_list=material_list, material=aluminium)
ifcopenshell.api.material.add_list_item(model,
material_list=material_list, material=glass)
else:
# IFC4+: Use IfcMaterialConstituentSet for named parts
constituent_set = ifcopenshell.api.material.add_material_set(model,
name="Window Assembly", set_type="IfcMaterialConstituentSet")
ifcopenshell.api.material.add_constituent(model,
constituent_set=constituent_set, material=aluminium, name="Frame")
ifcopenshell.api.material.add_constituent(model,
constituent_set=constituent_set, material=glass, name="Glazing")
Material + Style Integration
Materials define physical properties. Styles define visual appearance. These are separate concepts in IFC. ALWAYS apply both together for visual BIM models.
Workflow: Material + Visual Style
1. Create IfcMaterial → physical definition
2. Create IfcSurfaceStyle → visual appearance (color, texture)
3. Assign style to representation → visual display
4. Assign material to product → physical association
Materials and styles are NOT linked automatically. A material named "Concrete" does not automatically render as grey. The style must be explicitly created and assigned to the element's representation.