EXPRESS

Introduction

Let's take a look a very basic EXPRESS data model.

SCHEMA Family;

ENTITY Person
     name: STRING;
END_ENTITY;

We have defined a custom schema called Family. We have a Person class within this schema. The person has one attribute: name. The name is represented as a string.

If you are familiar with object oriented programming, then this should feel very straight forward. If not, check out:

Window Example

Let's take a look at our previous example, the window:

ENTITY IfcWindow
	SUBTYPE OF (IfcBuildingElement);
		OverallHeight : OPTIONAL IfcPositiveLengthMeasure;
		OverallWidth : OPTIONAL IfcPositiveLengthMeasure;
END_ENTITY;

We can see that we each "object" (window, wall, door, roof, etc.) is an ENTITY. Again, notice how we use the following format to specify an "object":

ENTITY { NAME }
    // content goes here
END_ENTITY;

Here's a list of some common building elements. These are defined in IFC2x Edition 3 Technical Corrigendum 1 schema, SCHEMA IFC2X3;. Again, notice how each building element ("object") is its own ENTITY.

Let's go back to our window. This is a Window class defined using the EXPRESS data model format.

SCHEMA IFC2X3; 

ENTITY IfcWindow
	SUBTYPE OF (IfcBuildingElement);
		OverallHeight : OPTIONAL IfcPositiveLengthMeasure;
		OverallWidth : OPTIONAL IfcPositiveLengthMeasure;
END_ENTITY;

Take a look at line 5 and 6. We can see that we have two attributes:

  1. Overall Height

  2. Overall Width

Missing Attributes?

Let's continue with our Window example. We saw that the windows has two attrbitues. However, according to the documentation, we're missing some attributes:

We can verify this by looking at the STEP-file. This has clearly more than two attributes:

#13067= IFCWINDOW('2cXV28XOjE6f6irgi0CO$D',#42,'M_Fixed:0915 x 1830mm:353953',$,'M_Fixed:0915 x 1830mm',#35337,#13061,'353953',1830.,914.999999999999);

We have 10 different attributes. Notice that we don't understand what any of these attributes mean.

Let's dive deep into EXPRESS

How does this work? How can we have more than two attributes?

SCHEMA IFC2X3; 

ENTITY IfcWindow
	SUBTYPE OF (IfcBuildingElement);
		OverallHeight : OPTIONAL IfcPositiveLengthMeasure;
		OverallWidth : OPTIONAL IfcPositiveLengthMeasure;
END_ENTITY;

Well, the answer lies within the EXPRESS definition. Take a close look at the 4th line above. We can see that IfcWindow is an subtype of an IfcBuildingElement. Here's the EXPRESS data model forIfcBuildingElement:

SCHEMA IFC2X3; 

ENTITY IfcBuildingElement
	 ABSTRACT SUPERTYPE OF (ONEOF
		(IfcBeam
		,IfcBuildingElementComponent
		,IfcBuildingElementProxy
		,IfcColumn
		,IfcCovering
		,IfcCurtainWall
		,IfcDoor
		,IfcFooting
		,IfcMember
		,IfcPile
		,IfcPlate
		,IfcRailing
		,IfcRamp
		,IfcRampFlight
		,IfcRoof
		,IfcSlab
		,IfcStair
		,IfcStairFlight
		,IfcWall
		,IfcWindow))
 	SUBTYPE OF (IfcElement);
END_ENTITY;

Notice how the IfcBuildingElement itself is a subtype of IfcElement (see line 25 above). Let's continue down the rabbit hole...

ENTITY IfcElement
	 ABSTRACT SUPERTYPE OF (ONEOF
		(IfcBuildingElement
		,IfcDistributionElement
		,IfcElectricalElement
		,IfcElementAssembly
		,IfcElementComponent
		,IfcEquipmentElement
		,IfcFeatureElement
		,IfcFurnishingElement
		,IfcTransportElement
		,IfcVirtualElement))
 	SUBTYPE OF (IfcProduct);
		Tag : OPTIONAL IfcIdentifier;
 INVERSE
		HasStructuralMember : SET [0:?] OF IfcRelConnectsStructuralElement FOR RelatingElement;
		FillsVoids : SET [0:1] OF IfcRelFillsElement FOR RelatedBuildingElement;
		ConnectedTo : SET [0:?] OF IfcRelConnectsElements FOR RelatingElement;
		HasCoverings : SET [0:?] OF IfcRelCoversBldgElements FOR RelatingBuildingElement;
		HasProjections : SET [0:?] OF IfcRelProjectsElement FOR RelatingElement;
		ReferencedInStructures : SET [0:?] OF IfcRelReferencedInSpatialStructure FOR RelatedElements;
		HasPorts : SET [0:?] OF IfcRelConnectsPortToElement FOR RelatedElement;
		HasOpenings : SET [0:?] OF IfcRelVoidsElement FOR RelatingBuildingElement;
		IsConnectionRealization : SET [0:?] OF IfcRelConnectsWithRealizingElements FOR RealizingElements;
		ProvidesBoundaries : SET [0:?] OF IfcRelSpaceBoundary FOR RelatedBuildingElement;
		ConnectedFrom : SET [0:?] OF IfcRelConnectsElements FOR RelatedElement;
		ContainedInStructure : SET [0:1] OF IfcRelContainedInSpatialStructure FOR RelatedElements;
END_ENTITY;

Again, notice how our IfcElement is a subtype of IfcProduct (see line 13 above). Let's continue...

ENTITY IfcProduct
			 ABSTRACT SUPERTYPE OF (ONEOF
				(IfcAnnotation
				,IfcElement
				,IfcGrid
				,IfcPort
				,IfcProxy
				,IfcSpatialStructureElement
				,IfcStructuralActivity
				,IfcStructuralItem))
			 SUBTYPE OF (IfcObject);
					ObjectPlacement : OPTIONAL IfcObjectPlacement;
					Representation : OPTIONAL IfcProductRepresentation;
			 INVERSE
					ReferencedBy : SET [0:?] OF IfcRelAssignsToProduct FOR RelatingProduct;
			 WHERE
					WR1 : (EXISTS(Representation) AND EXISTS(ObjectPlacement))
                		OR (EXISTS(Representation) AND 
                       (NOT('IFC2X3.IFCPRODUCTDEFINITIONSHAPE' IN TYPEOF(Representation))))
                    OR (NOT(EXISTS(Representation)));
END_ENTITY;

Our IfcProduct is a subtype of IfcObject (see line 11 above).

ENTITY IfcObject
	 ABSTRACT SUPERTYPE OF (ONEOF
			(IfcActor
			,IfcControl
			,IfcGroup
			,IfcProcess
			,IfcProduct
			,IfcProject
			,IfcResource))
	 SUBTYPE OF (IfcObjectDefinition);
			ObjectType : OPTIONAL IfcLabel;
	 INVERSE
				IsDefinedBy : SET [0:?] OF IfcRelDefines FOR RelatedObjects;
	 WHERE
				WR1 : SIZEOF(QUERY(temp <* IsDefinedBy | 'IFC2X3.IFCRELDEFINESBYTYPE' IN TYPEOF(temp))) <= 1;
END_ENTITY;

Our IfcObject is a subtype of IfcObjectDefinition (see line 10 above). Let's continue...

ENTITY IfcObjectDefinition
	 ABSTRACT SUPERTYPE OF (ONEOF
			(IfcObject
			,IfcTypeObject))
	 SUBTYPE OF (IfcRoot);
	 INVERSE
		HasAssignments : SET [0:?] OF IfcRelAssigns FOR RelatedObjects;
		IsDecomposedBy : SET [0:?] OF IfcRelDecomposes FOR RelatingObject;
		Decomposes : SET [0:1] OF IfcRelDecomposes FOR RelatedObjects;
		HasAssociations : SET [0:?] OF IfcRelAssociates FOR RelatedObjects;
END_ENTITY;

Our IfcObjectDefinition is a subtype of IfcRoot (see line 5 above). We are almost done...

ENTITY IfcRoot
 ABSTRACT SUPERTYPE OF (ONEOF
	(IfcObjectDefinition
	,IfcPropertyDefinition
	,IfcRelationship));
	GlobalId : IfcGloballyUniqueId;
	OwnerHistory : IfcOwnerHistory;
	Name : OPTIONAL IfcLabel;
	Description : OPTIONAL IfcText;
 UNIQUE
	UR1 : GlobalId;
END_ENTITY;

Finally, we have reached the end!

Inheritance

We call this behaivor inheritance.

  • IfcWindow

    • IfcBuildingElement

      • IfcProduct

        • IfcObject

          • IfcObjectDefinition

            • IfcRoot

Let's flip this "graph". This will make things a bit easier to explain.

  • IfcRoot

    • IfcObjectDefinition

      • IfcObject

        • IfcProduct

          • IfcBuildingElement

            • IfcWindow

We can see that IfcRoot has four different attributes; GlobalId, OwnerHistory, Name, Description. The IfcObjectDefinition will inherit these attributes. This means that the IfcWindow will inherit these attributes.

The IfcWindow will inherit all attributes from its parent entities.

Summary

If we use inheritance, we can see what each attribute in the STEP-file actually mean:

#13067= IFCWINDOW('2cXV28XOjE6f6irgi0CO$D',#42,'M_Fixed:0915 x 1830mm:353953',$,'M_Fixed:0915 x 1830mm',#35337,#13061,'353953',1830.,914.999999999999);

Or, we can simply look at the inheritance graph in the documentation:

Editor's note:

I know that this can hard to understand. Please, take a good look at this article. Read it agian, think and reflect about the content.

Last updated