| name | ifc-impl-data-enrichment |
| description | Use when adding descriptive data to elements that already exist in an IFC model: attaching a property set, an element quantity, a material, or a classification reference, without touching geometry or spatial structure. Prevents pointing IfcRelDefinesByProperties at a type object, putting a material usage entity on a type instead of an occurrence, naming a custom property set with the reserved Pset_ prefix, conflating quantities with properties, and duplicating one relationship per element. Covers the occurrence versus type attachment split, the HasPropertySets type mechanism, IfcRelAssociatesMaterial set-on-type usage-on-occurrence, IfcRelAssociatesClassification, and the Pset_ and Qto_ naming rules. Keywords: IFC enrichment, attach property set, IfcRelDefinesByProperties, IfcPropertySet, HasPropertySets, IfcElementQuantity, attach material, IfcRelAssociatesMaterial, IfcMaterialLayerSet, IfcMaterialLayerSetUsage, IfcRelAssociatesClassification, IfcClassificationReference, Pset_ prefix, Qto_ prefix, type versus occurrence, properties not showing on element, material on wrong element, how do I add data to an IFC element, how do I classify an IFC wall, why is my custom Pset ignored.
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires IFC IFC2x3,IFC4,IFC4.3. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
IFC Data Enrichment
Data enrichment is the write-side workflow of attaching descriptive data to
elements that already exist in a model: property sets, measured quantities,
materials, and classification references. Enrichment NEVER changes geometry
or spatial structure; it only adds the semantic layer that downstream tools
read for quantity take-off, cost, analysis, and compliance.
This skill covers the four enrichment targets, the occurrence-versus-type
attachment split, the Pset_ and Qto_ naming rules, and the material
set-on-type usage-on-occurrence pattern.
Verified against the IFC 4.3.2 specification (ISO 16739-1:2024) with IFC4
and IFC2x3 deltas noted inline. Applies to IFC2x3, IFC4, IFC4.3.
Quick Reference
The four enrichment targets
| Target | Container entity | Attachment to an occurrence | Attachment to a type |
|---|
| Properties | IfcPropertySet | IfcRelDefinesByProperties | HasPropertySets explicit attribute |
| Quantities | IfcElementQuantity | IfcRelDefinesByProperties | HasPropertySets explicit attribute |
| Material | IfcMaterial and the structured material entities | IfcRelAssociatesMaterial | IfcRelAssociatesMaterial |
| Classification | IfcClassificationReference | IfcRelAssociatesClassification | IfcRelAssociatesClassification |
Properties and quantities share one attachment machinery: IfcElementQuantity
is an IfcQuantitySet, which is an IfcPropertySetDefinition, the same
supertype as IfcPropertySet. Both ride IfcRelDefinesByProperties.
The occurrence versus type rule
IfcRelDefinesByProperties carries a WHERE rule NoRelatedTypeObject:
its RelatedObjects SET MUST NOT contain an IfcTypeObject.
- ALWAYS attach a property or quantity set to an OCCURRENCE through
IfcRelDefinesByProperties.
- ALWAYS attach a property or quantity set to a TYPE through the type's
HasPropertySets explicit attribute. NEVER point
IfcRelDefinesByProperties at a type object.
HasPropertySets is OPTIONAL SET [1:?] OF IfcPropertySetDefinition,
declared directly on IfcTypeObject. A type holds its sets inline; an
occurrence holds them through a relationship.
The material set versus usage rule
IfcRelAssociatesMaterial attaches a material to BOTH occurrences and
types, but the material object differs:
- The TYPE (
IfcWallType, IfcBeamType) ALWAYS takes the bare set:
IfcMaterialLayerSet or IfcMaterialProfileSet.
- The OCCURRENCE ALWAYS takes the usage entity:
IfcMaterialLayerSetUsage or IfcMaterialProfileSetUsage, which points
back at the same bare set via ForLayerSet or ForProfileSet and adds
placement. NEVER associate a usage entity with a type.
Naming rules
Pset_ is RESERVED for the standardised property set library
(Pset_WallCommon, Pset_BeamCommon). A custom property set NEVER uses
the Pset_ prefix; a Pset_-prefixed custom set collides with the
standard library and is silently misread.
Qto_ is the standardised quantity set prefix (Qto_WallBaseQuantities).
This convention is IFC4 and later. IFC2x3 used a BaseQuantities-style
convention; ALWAYS check the schema before writing a Qto_ name.
Decision Trees
Which enrichment do I need?
What am I adding to the element?
|
+- A descriptive or design attribute (fire rating, IsExternal,
| LoadBearing flag, thermal transmittance)
| -> IfcPropertySet, attached by IfcRelDefinesByProperties
|
+- A measured magnitude derived from geometry (gross area, net
| volume, count, weight, length)
| -> IfcElementQuantity, attached by IfcRelDefinesByProperties
|
+- The substance the element is made of
| -> IfcRelAssociatesMaterial (see the material decision tree)
|
+- A code from an external classification system (Uniclass,
OmniClass, MasterFormat, ETIM)
-> IfcRelAssociatesClassification
NEVER store a measured quantity inside an IfcPropertySet, and NEVER store
a design property inside an IfcElementQuantity. The two containers are
read by different tools.
Occurrence or type?
Is the data the same for every occurrence of this type?
|
+- Yes, it is shared by all occurrences (a wall type's standard
| layer build-up, a door type's fire rating)
| -> attach to the TYPE.
| Properties / quantities -> type.HasPropertySets
| Material -> IfcRelAssociatesMaterial with the
| bare set on the type
|
+- No, it varies per placed instance (this specific wall's
as-built area, this door's tag)
-> attach to the OCCURRENCE.
Properties / quantities -> IfcRelDefinesByProperties
Material -> IfcRelAssociatesMaterial with the
usage entity on the occurrence
When the same property name exists on both type and occurrence, the
OCCURRENCE value wins. Type values are defaults. See
ifc-impl-property-extraction for the read-side resolution.
Standard or custom property set?
Does a published Pset_ definition already cover this data?
|
+- Yes -> use the exact standard name (Pset_WallCommon) and the
| property names and value types it defines. NEVER alter
| the standard property names.
|
+- No -> create a custom property set. Its Name NEVER starts with
Pset_. Use a project or company prefix instead.
Which material structure?
How is the element made of its material(s)?
|
+- One homogeneous substance
| -> IfcMaterial directly as RelatingMaterial
|
+- Parallel layers (wall, slab, roof, plate)
| -> IfcMaterialLayerSet on the type,
| IfcMaterialLayerSetUsage on each occurrence
|
+- An extruded cross-section profile (beam, column, member, pile)
| -> IfcMaterialProfileSet on the type,
| IfcMaterialProfileSetUsage on each occurrence
| (IFC4+ only; this family does not exist in IFC2x3)
|
+- Named parts that are neither layered nor profiled (window
frame plus glazing, door panel plus hardware)
-> IfcMaterialConstituentSet (IFC4+; replaces IfcMaterialList)
In IFC2x3 a non-layered composite uses the legacy IfcMaterialList (a bare
LIST OF IfcMaterial). ALWAYS use IfcMaterialConstituentSet when
authoring IFC4 or IFC4.3.
Patterns
Every snippet uses STEP physical file syntax. $ marks an unset optional
attribute. Attribute order is the EXPRESS declared order. Full verified
signatures are in references/methods.md; runnable instances are in
references/examples.md.
Pattern: attach a property set to an occurrence
#48=IFCPROPERTYSINGLEVALUE('IsExternal',$,IFCBOOLEAN(.T.),$);
#49=IFCPROPERTYSET(
'1Hkj5pQ9X8x9bq0d6FZ7yA', /* GlobalId */
#5, /* OwnerHistory */
'Pset_WallCommon', /* Name */
$, /* Description */
(#48) /* HasProperties */
);
#50=IFCRELDEFINESBYPROPERTIES(
'2k7sB$Qe9X8x9bq0d6FZ7y', /* GlobalId */
#5, $, $, /* OwnerHistory, Name, Desc */
(#21,#22), /* RelatedObjects : occurrences */
#49 /* RelatingPropertyDefinition */
);
RelatedObjects is a SET [1:?]: one relationship serves many occurrences.
NEVER place an IfcWallType in RelatedObjects.
Pattern: attach a property set to a type
A type holds its sets inline through HasPropertySets. No relationship is
created.
#46=IFCPROPERTYSET(
'3mNp7rTf0Y9y0cr1e7GA8z',#5,'Pset_WallCommon',$,(#48));
#20=IFCWALLTYPE(
'4pQr9sUg1Z0z1ds2f8HB9$', /* GlobalId */
#5, 'Exterior 300mm', $, /* OwnerHistory,Name,Desc */
$, /* ApplicableOccurrence */
(#46), /* HasPropertySets */
$, /* RepresentationMaps */
$, /* Tag */
$, /* ElementType */
.STANDARD. /* PredefinedType */
);
HasPropertySets is the 6th explicit attribute of any IfcTypeObject
subtype. NEVER attach a type's properties with IfcRelDefinesByProperties.
Pattern: attach an element quantity
IfcElementQuantity uses the SAME relationship as a property set.
#70=IFCQUANTITYAREA('NetSideArea',$,$,12.5,$);
#71=IFCELEMENTQUANTITY(
'5qRs0tVh2$1$2et3g9IC0_', /* GlobalId */
#5, 'Qto_WallBaseQuantities', $,
$, /* MethodOfMeasurement */
(#70) /* Quantities */
);
#72=IFCRELDEFINESBYPROPERTIES(
'6rSt1uWi3_2_3fu4h0JD1A',
#5, $, $,
(#21), /* RelatedObjects */
#71 /* RelatingPropertyDefinition */
);
NEVER store a measured area as an IfcPropertySingleValue inside an
IfcPropertySet: quantity take-off tools read IfcElementQuantity only.
Pattern: associate a simple material
#80=IFCMATERIAL('Concrete C30/37',$,'concrete');
#81=IFCRELASSOCIATESMATERIAL(
'7sTu2vXj4A3A4gv5i1KE2B',
#5, $, $,
(#21,#22), /* RelatedObjects */
#80 /* RelatingMaterial */
);
RelatingMaterial accepts any IfcMaterialSelect choice. IfcMaterial is
the simplest. IfcRelAssociatesMaterial carries a WHERE rule
NoVoidElement: a material is NEVER associated with an IfcOpeningElement
or an IfcVirtualElement.
Pattern: associate a layered material
The bare set goes on the type; the usage goes on each occurrence.
/* bare set, associated with the IfcWallType */
#90=IFCMATERIALLAYER(#80,0.3,$,'Core',$,'LoadBearing',$);
#91=IFCMATERIALLAYERSET((#90),'EXT-300',$);
#92=IFCRELASSOCIATESMATERIAL(
'8tUv3wYk5B4B5hw6j2LF3C', #5, $, $, (#20), #91);
/* usage, associated with the IfcWall occurrence */
#93=IFCMATERIALLAYERSETUSAGE(#91,.AXIS2.,.POSITIVE.,-0.15,$);
#94=IFCRELASSOCIATESMATERIAL(
'9uVw4xZl6C5C6ix7k3MG4D', #5, $, $, (#21), #93);
IfcMaterialLayerSetUsage.ForLayerSet (#91) points back at the same bare
set the type uses. NEVER associate an IfcMaterialLayerSetUsage with a
type, and NEVER associate a bare IfcMaterialLayerSet with an occurrence
when the type is available.
Pattern: associate a classification
#60=IFCCLASSIFICATION($,'2015',$,'Uniclass 2015',$,$,$);
#61=IFCCLASSIFICATIONREFERENCE(
$, /* Location */
'EF_25_10', /* Identification */
'Walls', /* Name */
#60, /* ReferencedSource: the IfcClassification */
$, $ /* Description, Sort */
);
#62=IFCRELASSOCIATESCLASSIFICATION(
'AvWx5yAm7D6D7jy8l4NH5E',
#5, $, $,
(#21,#22), /* RelatedObjects */
#61 /* RelatingClassification */
);
IfcClassification names the SYSTEM; IfcClassificationReference names one
CODE inside it. ALWAYS set ReferencedSource so a reader can resolve the
code to its system. RelatingClassification accepts either entity.
Pattern: share one definition across many elements
RelatedObjects on every enrichment relationship is a SET [1:?]. ALWAYS
list every receiving element in ONE relationship rather than cloning the
relationship per element.
#50=IFCRELDEFINESBYPROPERTIES(
'2k7sB$Qe9X8x9bq0d6FZ7y', #5, $, $,
(#21,#22,#23,#24), /* four walls, one relationship */
#49);
One IfcRelDefinesByProperties per property set, not per element. The same
holds for IfcRelAssociatesMaterial and IfcRelAssociatesClassification.
Anti-Patterns
Full detail with the failure mechanism is in references/anti-patterns.md.
The ones that matter most:
- Pointing
IfcRelDefinesByProperties at a type object. The WHERE rule
NoRelatedTypeObject rejects it; types use HasPropertySets.
- Putting an
IfcMaterialLayerSetUsage on a type. The usage is occurrence
only; the type takes the bare IfcMaterialLayerSet.
- Naming a custom property set with the
Pset_ prefix. It collides with
the standard library and is misread or ignored.
- Storing a measured quantity inside an
IfcPropertySet. Quantity take-off
tools read IfcElementQuantity only.
- Cloning one relationship per element instead of listing every element in
the single relationship's
RelatedObjects SET.
- Setting
IfcMaterialLayerSet.TotalThickness by hand. It is a DERIVED
attribute computed by the schema.
Reference Links
This skill
references/methods.md: full positional attribute signatures for every
enrichment entity, with supertypes and version notes.
references/examples.md: verified STEP physical file instances.
references/anti-patterns.md: failure modes and their root causes.
Related skills
ifc-syntax-property-sets: building the IfcPropertySet and its
IfcProperty value entities.
ifc-syntax-materials: the structured material entities in full.
ifc-syntax-classifications: IfcClassification and the external
classification systems.
ifc-impl-property-extraction: the read-side type-versus-occurrence
property override resolution.
ifc-core-relationships: the objectified relationship pattern.
Official sources