Developer Guide
Application Structure
System Architecture
The Validation Service is built on django, using Postgres as the database, Redis for task management, and Celery for distributing the work of running the validation tasks. The service consists of multiple containers managed with Docker compose.
Submodules
The application consists of three main submodules, each hosted in separate GitHub repositories. Docker Compose is configured to automatically bind the correct submodule versions for local deployment.
Documentation of the separate functionalities can be found within each submodule.
File Parser: A module within IfcOpenShell, dedicated to parsing files.
Gherkin Rules: Contains the rules for validation. It can be run independently by cloning the repository and executing:
pytest -sv
Debugging individual rules is supported with commands like:
python test/test_main.py alb001 # For a single rule python test/test_main.py alb001 alb002 # For multiple rules python test/test_main.py path_to_separate_file.py # For a separate file
Shared DataModel: This module includes Django data models shared between the main repository and the Gherkin repository, serving as a submodule for both.
Running Validation Checks
The application supports multiple validation checks on one or multiple IFC files that can be run separately:
Syntax Check
Schema Check
Normative Rules (gherkin) Check
bSDD Check
How to start?
Depending on your workflow, you can run all or some services via Docker Compose.
Below are a few common options to run and debug these services locally. More scenario’s exist - have a look at the various make files.
Option 1 - Run minimal set of services via Docker Compose (easiest to run)
Make sure Docker is running.
Start all services.
make start
or
docker compose up
This pulls Docker-hub images, builds and spins up six different services:
db - PostgreSQL database
redis - Redis instance
backend - Django Admin + API's
worker - Celery worker
flower - Celery flower dashboard
frontend - React UI
One-time only: create Django superuser accounts for Django Admin and Celery background worker(s), for example:
docker exec -it backend sh
cd backend
DJANGO_SUPERUSER_USERNAME=root DJANGO_SUPERUSER_PASSWORD=root DJANGO_SUPERUSER_EMAIL=root@localhost python3 manage.py createsuperuser --noinput
DJANGO_SUPERUSER_USERNAME=SYSTEM DJANGO_SUPERUSER_PASSWORD=system DJANGO_SUPERUSER_EMAIL=system@localhost python3 manage.py createsuperuser --noinput
exit
Navigate to different services:
Validation Service - React UI: http://localhost
Django Admin UI: http://localhost/admin (or http://localhost:8000/admin) - default user/password: root/root
Django API - Swagger: http://localhost/api/swagger-ui
Django API - Redoc: http://localhost/api/redoc
Celery Flower UI: http://localhost:5555
Optionally, use a tool like curl or Postman to invoke API requests directly
Option 2 - Local debugging + infrastructure via Docker Compose (easiest to debug)
Make sure Docker is running.
Start infrastructure services only (Redis, Postgres, Celery Flower)
make start-infra
or
docker compose -f docker-compose.infra_only.yml up
This pulls three different Docker-hub images and spins up services:
db - PostgreSQL database
redis - Redis instance
flower - Celery flower dashboard
Start Django backend (Admin + API)
cd backend
make install
make start-django
Start Celery worker(s)
cd backend
make start-worker
Start Node Development server to serve the React UI
cd frontend
npm install
npm run start
One-time only: create Django superuser accounts for Django Admin and Celery background worker(s), for example:
cd backend
DJANGO_SUPERUSER_USERNAME=root DJANGO_SUPERUSER_PASSWORD=root DJANGO_SUPERUSER_EMAIL=root@localhost python3 manage.py createsuperuser --noinput
DJANGO_SUPERUSER_USERNAME=SYSTEM DJANGO_SUPERUSER_PASSWORD=system DJANGO_SUPERUSER_EMAIL=system@localhost python3 manage.py createsuperuser --noinput
Navigate to different services:
Validation Service - React UI: http://localhost:3000
Django Admin UI: http://localhost:8000/admin - default user/password: root/root
Django API - Swagger: http://localhost:8000/api/swagger-ui
Django API - Redoc: http://localhost:8000/api/redoc
Celery Flower UI: http://localhost:5555
Optionally, use a tool like curl or Postman to invoke API requests directly
IFC Gherkin rules
Usage as part of buildingSMART validation service
This repository is one of three submodules in the overall validation service. See application_structure for more information.
Making changes
The rules developed in this repository follow the general ideas of Gherkin and its python implementation behave.
This means there are human-readable definitions of rules and Python implementations.
A third component of this repository are minimal sample files with expected outcomes, which means that extensions and modifications can be suggested with confidence of not breaking existing functionality.
Command line usage
Informal propositions and implementer agreements written in Gherkin for automatic validation of IFC building models using steps implemented in IfcOpenShell.
$ python -m ifc-gherkin-rules ifc-gherkin-rules\test\files\gem001\fail-gem001-cube-advanced-brep.ifc
Feature: Shell geometry propositions/IfcClosedShell.v1
URL: /blob/8dbd61e/features/geometry.shells.feature
Step: Every oriented edge shall be referenced exactly 1 times by the loops of the face
* #29=IfcClosedShell((#104,#115,#131,#147,#163,#179))
On instance #29=IfcClosedShell((#104,...,#179)) the edge (-0.183012701892219,
0.683012701892219, 1.0) -> (-0.683012701892219, -0.183012701892219, 1.0) was
referenced 2 times
* #29=IfcClosedShell((#104,#115,#131,#147,#163,#179))
On instance #29=IfcClosedShell((#104,...,#179)) the edge (-0.5, -0.5, 0.0) ->
(-0.5, 0.5, 0.0) was referenced 2 times
* #29=IfcClosedShell((#104,#115,#131,#147,#163,#179))
On instance #29=IfcClosedShell((#104,...,#179)) the edge (-0.5, 0.5, 0.0) ->
(0.5, 0.5, 0.0) was referenced 2 times
* #29=IfcClosedShell((#104,#115,#131,#147,#163,#179))
On instance #29=IfcClosedShell((#104,...,#179)) the edge (-0.683012701892219,
-0.183012701892219, 1.0) -> (0.183012701892219, -0.683012701892219, 1.0) was
referenced 2 times
* #29=IfcClosedShell((#104,#115,#131,#147,#163,#179))
On instance #29=IfcClosedShell((#104,...,#179)) the edge (0.183012701892219,
-0.683012701892219, 1.0) -> (0.683012701892219, 0.183012701892219, 1.0) was
referenced 2 times
* #29=IfcClosedShell((#104,#115,#131,#147,#163,#179))
On instance #29=IfcClosedShell((#104,...,#179)) the edge (0.5, -0.5, 0.0) ->
(-0.5, -0.5, 0.0) was referenced 2 times
* #29=IfcClosedShell((#104,#115,#131,#147,#163,#179))
On instance #29=IfcClosedShell((#104,...,#179)) the edge (0.5, 0.5, 0.0) ->
(0.5, -0.5, 0.0) was referenced 2 times
* #29=IfcClosedShell((#104,#115,#131,#147,#163,#179))
On instance #29=IfcClosedShell((#104,...,#179)) the edge (0.683012701892219,
0.183012701892219, 1.0) -> (-0.183012701892219, 0.683012701892219, 1.0) was
referenced 2 times
Detailed Information for Normative Rules
Follow these steps to add a new rule to the Validation Service
n. |
Step |
Responsible |
---|---|---|
1 |
Create a new branch in the bSI ifc-gherkin-rules repository |
bSI Validation Service team |
2 |
In this branch, start developing the rule needed following instructions below |
rule developer |
3 |
Create a pull request to further test the rule(s) behavior using the sandbox environment |
rule developer |
4 |
Assign a reviewer to the pull request when you think the rule is ready to be merged |
rule developer |
5 |
Review the pull request |
bSI Validation Service team |
6 |
(optional) Fix the rule according to feedback from reviewer |
rule developer |
7 |
Approve and merge the pull request |
bSI Validation Service team |
1. Branch creation
In the buildingSMART GitHub repository containing all rules, create the branch that will be used to develop the new rule.
Name the branch with the name of the new rule. Example:
GEM900
for a new rule in the geometry functional partAdd 1 rule per branch, to facilitate review (1 rule = 1
.feature
file)
2. Rule development
A rule is considered complete when it has:
a Gherkin feature file
corresponding python implementation (aka, python steps)
a set of unit test files
Below are instructions for all these 3 components.
2.1) Write feature files (gherkin rules) for IFC
A feature file is a file, written using Gherkin syntax, describing the rule behavior. In the branch just created, add a Gherkin feature file following these instructions.
File format: .feature
Location: https://github.com/buildingSMART/ifc-gherkin-rules/tree/main/features
Naming convention for feature files
The file name is rule code_rule title
The rule code is made of 3 digits capital letters (taken from the list of Functional parts) + 3 digits number
The rule code, and rule title, must be unique
The rule title shall have no space and shall use
-
as separator
wrong
SPS001 - Basic-spatial-structure-for-buildings.feature
SPS001_Basic spatial structure for buildings.feature
SPS001 - Basic spatial structure for buildings.feature
right
SPS001_Basic-spatial-structure-for-buildings.feature
Mandatory content
.feature
files:
must include one and only one of these tags to classify the validation category:
@critical
@implementer-agreement
@informal-proposition
@industry-practice
(warning; not a pass / fail)
must include a 3-character alpha tag to the functional part. See Functional parts
must include a single tag indicating the version of the feature file as a 1-based integer
Example:
@version1
for initial version of a feature fileExample:
@version3
for the third version of a feature fileMinor changes such as fixing typos or re-wording the description do not increment the version
Any change to a “Given” or “Then” statement, or to a step implementation, requires the version number to be incremented by 1.
must include one or more tags indicating the error code to be raised
If all scenarios raise the same error, then this tag should be placed immediately above the “Feature:” line
example
@implementer-agreement @GRF @version1 @E00050 Feature: GRF001 - Identical....
If some scenarios raise different error codes, then this tag should be placed immediately above each **”Scenario” ** line
example
@implementer-agreement @ALS @version1 Feature: ALS005 - Alignment shape representation Background: ... @E00020 Scenario: Agreement on ... representation - Value @E00010 Scenario: Agreement on ... representation - Type
must include exactly 1 Feature
the naming convention for the Feature is the following: rule code - rule title (the same used for the file name). For the rule title blank spaces must be used instead of
-
wrong
Feature: ALB001_Alignment Layout
Given ...
Then ...
@ALB
Feature: ALB001_Alignment-Layout
Given ...
Then ...
@ALB
Feature: ALB001 - Alignment-Layout
Given ...
Then ...
right
@ALB
Feature: ALB001 - Alignment Layout
Given ...
Then ...
must include a description of the rule that start with “The rule verifies that…”
example
@implementer-agreement
@ALB
Feature: ALB003 - Allowed entities nested in Alignment
The rule verifies that an Alignment has a nesting relationship with its components (i.e., Horizontal, Vertical, Cant layouts) or with Referents (e.g., mileage markers). And not with any other entity.
Scenario: Agreement on nested elements of IfcAlignment
Given ...
Then ...
Mandatory Given(s)
If the rule in the feature file applies only to specific IFC version(s) and/or View Definition(s), then the feature file (or each of its Scenarios, if it has more than one) must start with Given steps specifying the applicability of the following steps
examples
Given A model with Schema "IFC2X3"
Given A file with Model View Definition "CoordinationView"
Given A model with Schema "IFC2X3" or "IFC4"
Given A file with Model View Definition "CoordinationView" or "ReferenceView"
Optional content
.feature
files:
can include 1 or more Scenarios
Scenario titles have no constraints
can include the
@disabled
tag to temporarily remove them from processing
No spaces between steps
wrong
Given A model with Schema "IFC4.3"
Then Each IfcAlignmentHorizontal must be nested only by 1 IfcAlignment
Then Each IfcAlignmentVertical must be nested only by 1 IfcAlignment
Then Each IfcAlignmentCant must be nested only by 1 IfcAlignment
right
Given A model with Schema "IFC4.3"
Then Each IfcAlignmentHorizontal must be nested only by 1 IfcAlignment
Then Each IfcAlignmentVertical must be nested only by 1 IfcAlignment
Then Each IfcAlignmentCant must be nested only by 1 IfcAlignment
Watch out for extra blank spaces
wrong
Given A model with Schema "IFC4.3"
Then Each IfcAlignmentHorizontal must be nested only by 1 IfcAlignment
Then Each IfcAlignmentVertical must be nested only by 1 IfcAlignment
Then Each IfcAlignmentCant must be nested only by 1 IfcAlignment
right
Given A model with Schema "IFC4.3"
Then Each IfcAlignmentHorizontal must be nested only by 1 IfcAlignment
Then Each IfcAlignmentVertical must be nested only by 1 IfcAlignment
Then Each IfcAlignmentCant must be nested only by 1 IfcAlignment
Do not use punctuation at the end of the steps
wrong
Given A model with Schema "IFC4.3",
Then Each IfcAlignmentHorizontal must be nested only by 1 IfcAlignment;
Then Each IfcAlignmentVertical must be nested only by 1 IfcAlignment;
Then Each IfcAlignmentCant must be nested only by 1 IfcAlignment.
right
Given A model with Schema "IFC4.3"
Then Each IfcAlignmentHorizontal must be nested only by 1 IfcAlignment
Then Each IfcAlignmentVertical must be nested only by 1 IfcAlignment
Then Each IfcAlignmentCant must be nested only by 1 IfcAlignment
Be careful when typing parameters. They are case-sensitive!
wrong
Given A model with schema "IFC4.3",
right
Given A model with Schema "IFC4.3"
Must vs Shall
Use must, not shall to impose requirements. ALB001_Alignment-in-spatial-structure.feature “Shall” is ambiguous, also in the legal field the community is moving to a strong preference for “must” as the clearest way to express a requirement or obligation.
wrong
Given A model with Schema "IFC2X3"
Given A file with Model View Definition "CoordinationView"
Then There shall be exactly 1 IfcSite element(s)
right
Given A model with Schema "IFC2X3"
Given A file with Model View Definition "CoordinationView"
Then There must be exactly 1 IfcSite element(s)
Verbs for IFC relationships
When a rule requires a specific IFC relationship to exist, refer to the table below for the right verb to be used.
IFC relationship |
Verb for rules |
Examples |
---|---|---|
IfcRelAggregates |
aggregate, aggregates |
Then IfcSite must aggregate IfcBuilding |
IfcRelNests |
nest, nests |
Then Each IfcAlignmentVertical nests a list of IfcAlignmentSegment |
… |
Reference for schema versioning
Rules that are applicable only to specific schema versions must specify
the schema version with the initial Given
statement.
For example, alignment entities were introduced in IFC4.3 and are not valid in earlier schema versions.
Given A model with Schema "IFC4.3"
Given An IfcAlignment
Then ...
Multiple schema versions may be specified if applicable.
Given A model with Schema "IFC2X3" or "IFC4"
Given An IfcElement
Then ...
Valid (active, not withdrawn or retired) Schema Versions
Version |
Formal Name |
Schema id |
Common Name |
---|---|---|---|
4.3.2.0 |
IFC4.3 ADD2 |
IFC4X3_ADD2 |
IFC4.3 |
4.0.2.1 |
IFC4 ADD2 TC1 |
IFC4 |
IFC4 |
2.3.0.1 |
IFC2x3 TC1 |
IFC2X3 |
IFC2x3 |
2.2) Write python steps
The python steps are the implementation (using python language) of the Gherkin grammar used in the feature files. In the same branch used for the Gherkin rules, change or add python steps following these instructions.
File format: .py
Location: https://github.com/buildingSMART/ifc-gherkin-rules/tree/main/features/steps
Naming convention for python files
For the moment, all python steps are contained in steps.py. Therefore, you should not create a new python file, just expand the existing one.
:construction: :construction: :construction: In the future, when this file grows, python steps may be splitted in more files - using a certain criteria (e.g., functional parts). When this will be the case, the instruction will be: locate the best .py file to host your steps and start adding your steps
Steps parametrisation
When creating a new step, think about parametrisation and optimisation of the step for future uses.
Step re-use
Before creating a new step, check if something similar already exist. Try to reuse existing steps.
Do not use “when” or “And” keywords
The “when” keyword must not be used. The “And” keyword must not be used. Instead, repeat the “Given” or “Then” as appropriate.
Allowed keywords are: Given
, and Then
.
Use of existing IfcOpenShell APIs
Try not to use existing functionality included in the ifcopenshell.api
namespace.
2.3) Write unit test files
Unit test files are atomic IFC files, created to develop a rule and test its behavior. In the same branch used for the Gherkin rules, and python steps, create unit test files following these instructions. IMPORTANT: every rule developed must have a set of unit test files.
File format: .ifc
Location:ifc-gherkin-rules/tree/main/test/files
in the test/files folder, create a subfolder using the rule code (E.g., ALB001)
add the set of unit test files for that rule in this subfolder
Naming convention for unit test files
Unit test files must follow this naming convention:
Expected result
-rule code
-rule scenario
-short_informative_description
.ifc
Or in case where a rule has no scenarios:
Expected result
-rule code
-short_informative_description
.ifc
Examples
pass-alb001-short_informative_description.ifc
fail-alb001-scenario01-short_informative_description.ifc
fail-alb001-short_informative_description.ifc
Content of the unit tests subfolder
The unit test subfolder must contain:
all unit test files (.ifc)
a README file (.md), listing the files and their expected behavior. Using the template table below
where used, the script (.py) created to generate the unit test files
Number of unit tests required
Each rule developed must have a set of unit test files
There must be at least 1 fully compliant unit test file
Fail files must cover all scenarios of the rule
Table template for unit test files
Example table describing unit test expected results
File name |
Expected result |
Error log |
Description |
---|---|---|---|
pass-alb002-alignment-layout |
success |
n.a. |
|
fail-alb002-scenario01-nested_attributes_IfcAlignment |
fail |
The instance IfcAlignment is nesting two instances of IfcAlignmentHorizontal … |
Error is descriptive or exactly the error in pytest? If exactly, multiple row… |
fail-alb002-scenario02-two_alignments |
fail |
The following 2 instances were encountered: IfcAlignment #23, IfcAlignment #906 |
For IfcAlignmentHorizontal, IfcAlignmentVertical and IfcAlignmentCant |
fail-alb002-scenario03-layout |
fail |
The instance #906=IfcAlignment is nesting #907=IfcWall |
Includes errors for scenario 2 |
fail-alb002-scenario04-alignment_segments |
fail |
The instance (s) #28=IfcAlignmentHorizontal is assigned to #906=IfcWall |
@todo IfcAlignmentVertical, IfcAlignmentCant. As well as empty list/typo’s? |
4. Assign a reviewer to the pull request
…
5. Review the pull request
…
6. (optional) Fix the rule according to feedback from reviewer
…
7. Approve and merge the pull request
…
Appendix
Error Codes
Error codes are used to classify and categorize outcomes from the validation service and are implemented in ifc-validation-data-model/main/models.py#L937.
Error Code |
Description |
---|---|
P00010 |
Passed |
N00010 |
Not Applicable |
E00001 |
Syntax Error |
E00002 |
Schema Error |
E00010 |
Type Error |
E00020 |
Value Error |
E00030 |
Geometry Error |
E00040 |
Cardinality Error |
E00050 |
Duplicate Error |
E00060 |
Placement Error |
E00070 |
Units Error |
E00080 |
Quantity Error |
E00090 |
Enumerated Value Error |
E00100 |
Relationship Error |
E00110 |
Naming Error |
E00120 |
Reference Error |
E00130 |
Resource Error |
E00140 |
Deprecation Error |
E00150 |
Shape Representation Error |
E00160 |
Instance Structure Error |
W00010 |
Alignment Contains Business Logic Only |
W00020 |
Alignment Contains Geometry Only |
W00030 |
Warning |
X00040 |
Executed |
Notes
Not Applicable
refers to a rule that does not apply because of the schema version.
Executed
refers to a rule that does apply because of schema version,
but the model does not contain any entities validated as part of a particular rule.
Both outcomes are reported as “N/A” in the validation service user interface.
Functional parts
Functional parts refer to logical grouping of rules that involve similar types of validation.
These functional part prefixes are used in the naming of the normative rules and are reported in the results listed by the validation service.
Catalog
Below is the list of the IFC functional parts.
TAG |
FUNCTIONAL PART |
DESCRIPTION |
---|---|---|
PJS |
Project definition |
The ability to define the overall context and directory of objects within the model. Among others, the context definition includes default units and geometric representation context for shape representations. |
GRF |
Georeferencing |
The ability to accurately define the geographic location and orientation of the model relative to a reference coordinate system, such as a national or global coordinate system. |
BLT |
Built elements (kickable) |
The ability to model various building and infrastructure elements, including walls, floors, roofs, stairs, doors, windows, columns, road pavements, bridge decks, railway track elements, etc. |
ASM |
Assemblies (kickable) |
The ability to model elements composed of / constructed by other elements. For example, a roof might be assembled from a series of prefabricated truss components. |
SPA |
Spaces (non-kickable) |
The ability to model spaces, such as rooms, hallways, clearance zones, and circulation areas. |
VRT |
Virtual elements (non-kickable) |
The ability to model spatial element used to provide imaginary, placeholder, or provisional areas (e.g. clearance), volumes, and boundaries. Virtual elements are not displayed, do not have quantities, materials, or other measures. |
GEM |
*Geometry representation |
The ability to represent built elements and spaces using various geometry types, including parametric, mesh, and voxel-based representations. |
OJP |
*Object placement |
The ability to define the location, orientation, and scale of built elements and systems within the building model. |
POS |
*Positioning elements |
The ability to define (virtual) objects that are used to position other elements relatively. Includes grids, alignments, and referents. |
OJT |
Objects typing |
The ability to define elements (and unfortunately not systems) based on their type or function within the model, allowing reusability of information by the occurrence of such types. |
GRP |
Groups (non-kickable) |
The ability to group objects related by functional or logical criteria. Used, for example to model building systems, such as HVAC (heating, ventilation, and air conditioning) systems; to group assets that have the same maintenance schedule; to group all terminals of a fire-protection system. |
SPS |
Spatial breakdown |
The ability to define spatial organisation within a building or infrastructure project. This includes the hierarchical relationships between spatial containers, such as buildings within a site, storeys within a building and rooms within a storey. |
MAT |
Materials |
The ability to define materials assigned to elements. |
PSE |
Properties for object |
The ability to define properties of elements and systems, such as their performance characteristics. |
QTY |
Quantities for objects |
The ability to define quantities of elements, such as their dimensions, volume, area, weight. |
CLS |
Classification reference |
The ability to classify elements, materials, and systems according to various classification systems, such as the UNIFORMAT or Omniclass classification systems. |
ANN |
Annotations |
The ability to add annotations to elements and spaces, such as labels, notes, and dimensions. |
LAY |
Presentation layer |
The ability to assign layers (also known as, CAD layer) to collection of elements. This is used mainly for grouping and visibility control, and in general to organise geometry into groups that may be shown or hidden. |
CTX |
Presentation Colours and Textures |
The ability to assign colour, texture and other presentation appearance information to objects. |
POR |
Port connectivity & nesting |
The ability to define ports (as means for an element to connect to other elements) and the relationship that is made between two ports. |
STR |
Structural items and actions |
The ability to define structural members and structural connections, as analysis idealizations of built elements. And the ability to define actions (such as forces, displacements, etc.) and reactions (support reactions, internal forces, deflections, etc.) associated to structural items and specified by using the basic load definitions. |
CST |
Costing |
The ability to assign costing information to objects. |
SDL |
Scheduling of activities |
The ability to assign scheduling information to objects. |
LIB |
Library reference |
The ability to associate library entities, such as from a product library or external database to objects and object types. |
DOC |
Documentation reference |
The ability to associate reference to documentation to objects. |
CTR |
Constraints |
The ability to model constraints on building elements, such as minimum and maximum dimensions or clearances, and to enforce these constraints during design and construction. |
VER |
Versioning / revision control |
The ability to track changes to building data over time and to maintain a history of changes. |
*These 3 functional parts are further decomposed as indicated below.
Geometry representation sub-parts
TAG |
FUNCTIONAL PART |
DESCRIPTION |
---|---|---|
AXG |
Axis geometry |
This involves representing the geometry using a set of axes, where each axis consists of a position in 3D space and a direction vector. This can be useful for representing geometry that follows a certain pattern or direction, such as walls, beams, columns, or other elements. In IFC, axis geometry can be represented using the IfcCartesianPoint and IfcDirection classes, which define the position and direction of the axes, respectively. |
ALS |
Alignment geometry |
This involves representing the geometry using a collection of segments that define a linear path in 3D space. This can be useful for representing linear objects such as roads, railways, or pipelines. |
PBG |
Point-based geometry |
This involves representing geometry using a collection of individual points in 3D space. Point-based geometry can be useful for representing large-scale environments or for creating simplified representations of more complex geometry. Point-based geometry can be represented in IFC using a range of different point types, such as 3D point clouds or scattered point data. |
TAS |
Tessellated (i.e. meshes) |
This involves representing geometry using a collection of interconnected vertices, edges, and faces, which are used to approximate a smooth surface. Tessellated geometry can be useful for representing organic or irregular shapes, or for creating low-resolution representations of more complex geometry. In IFC, tessellated geometry can be represented using a range of different mesh types, such as triangular, quadrilateral, or polyhedral meshes. |
BRP |
Boundary Representation (BREP) |
This involves representing geometry using a collection of connected surfaces and edges. BREP geometry can be used to represent complex shapes with curved surfaces or unusual topology. BREP geometry can be represented in IFC using IfcFacetedBrep for polygonal meshes or IfcManifoldSolidBrep for more complex solid geometry. These entities can be further described using a collection of geometric representations such as IfcCartesianPoint, IfcPolyLoop, and IfcSurface. |
CSG |
Constructive Solid Geometry (CSG) |
This involves creating complex geometry by combining simpler shapes using Boolean operations such as union, intersection, and difference. CSG can be useful for creating complex shapes with predictable and repeatable geometry. CSG can be represented in IFC using the IfcBooleanResult entity, which defines the Boolean operation to be applied to a set of one or more shape representations. |
SWE |
Sweeps (i.e., extrusions, lofts, blends) |
This involves taking a 2D shape (often called the “profile”) and moving it along a 3D path, generating a 3D shape. The resulting shape is typically smooth and continuous, with its cross-section changing gradually along the length of the path. Sweep geometry can be useful for representing a variety of objects, such as pipes, cables, and architectural details like moldings. In IFC, sweep geometry can be represented using the IfcExtrudedAreaSolid, IfcRevolvedAreaSolid, and IfcSweptAreaSolid entities. |
TFM |
Transformations |
Transformation geometry involves representing geometry using spatial transformations, such as rotations, translations, and scaling. It allows for the modification of existing geometry without the need to create new geometry from scratch. Transformation geometry can be used to represent various types of transformations, including cartesian transformations, placement transformations, and composite transformations, among others. These transformations can be applied to a range of geometric entities, including points, curves, surfaces, and solids, to create new or modified geometry. In IFC, transformation geometry is represented using the IfcCartesianTransformationOperator and IfcObjectPlacement entities. |
BBX |
Bounding box |
This involves defining an orthogonal box, oriented parallel to the axes of the object coordinate system in which it is defined and containing a geometry object, which defines the spatial extent of the latter. |
MPD |
Mapped geometry |
This involves identifying a representation and a representation item in that representation for the purpose of mapping. The representation item defines the origin of the mapping. The representation map is used as the source of a mapping by a mapped item. |
RCO |
Relational constructs |
Such as connection geometry, space boundaries, interference geometries. This is not a geometry category per se, but it’s a specific way geometry is used in IFC |
CPD |
Clipped representations |
This involves visualizations of a 3D model where part of the model is “clipped” or cut away to allow for better examination of the internal structures or components. This is often done using clipping planes or sections. |
Object placement sub-parts
TAG |
FUNCTIONAL PART |
DESCRIPTION |
---|---|---|
LOP |
Local placement |
The ability to define the placement of a product in relation to the placement of another product; or its absolute placement within the geometric representation context of the project. |
LIP |
Linear placement |
The ability to define the placement of a product in relation to a curve. |
GDP |
Grid placement |
The ability to define the placement of a product in relation to a design grid. |
Positioning elements sub-parts
TAG |
FUNCTIONAL PART |
DESCRIPTION |
---|---|---|
GRD |
Grid |
The ability to define a design grid to be used as reference for object placement. |
ALA, ALB |
Alignment |
The ability to define an alignment curve, and its components. These can be used as reference for object placement. |
RFT |
Referent |
The ability to define a referent to be used as reference for object placement. |
A deep dive into gherkin rule implementations
Decorators
@gherkin_ifc
This is used in place of behave
’s default @step_implementation
decorator
to provide additional capabilities related to context stacking and other concerns
related to tracking and evaluating instances in the IFC model.
@register_enum_type
This is a small new decorator for registering enumeration types in a simpler way.
Step handling
execute_step()
Checks whether the current step being processed is a Given
or Then
.
handle_given()
Handles a Given
step.
handle_then()
Handles a Then
step.
Context stacking
As steps are processed, they are captured in a persistent object of type behave.runner.Context
.
This context object includes a hidden attribute _stack
that is used to ‘stack’ information
and results for each step that is processed.
It can be helpful to monitor the content of the instances
attribute of each item in the
context._stack
list.