ifcopenshell

Welcome to IfcOpenShell! IfcOpenShell provides a way to read and write IFCs.

IfcOpenShell can open IFC files, read entities (such as walls, buildings, properties, systems, etc), edit attributes, write out .ifc files and more.

This module provides primitive functions to interact with IFC, including:

  • For most users, you can open and read IFC models, see docs for open(). This returns an file object representing the IFC model. You can then query the model to filter elements.

  • For developers, you can query the schema itself, see docs for schema_by_name(). This returns a schema object which you can use to analyse the definitions of IFC classes and data types.

You may also be interested in:

For more details, consult https://docs.ifcopenshell.org/

Example:

import ifcopenshell

print(ifcopenshell.version)

model = ifcopenshell.open("/path/to/model.ifc")
walls = model.by_type("IfcWall")

for wall in walls:
    print(wall.Name)

Subpackages

Submodules

Package Contents

class ifcopenshell.entity_instance(e: ifcopenshell.ifcopenshell_wrapper.entity_instance | tuple[str, str], file: ifcopenshell.file | None = None)

Represents an entity (wall, slab, property, etc) of an IFC model

An IFC model consists of entities. Examples of entities include walls, slabs, doors and so on. Entities can also be non-physical things, like properties, systems, construction tasks, colours, geometry, and more.

Entities are defined through an IFC Class. There are hundreds of IFC Classes defined as part of the ISO standard by the buildingSMART International organisation. The IFC Class defines the attributes of an entity, as well as the data types and whether or not an attribute is mandatory or optional.

IfcOpenShell’s API dynamically implements the IFC schema. You will not find documentation about available IFC Classes, or what attributes they have. Please consult the buildingSMART official documentation or start reading Introduction to IFC.

In addition to the Python methods you see documented here, an instantiated entity_instance will have attributes defined by its IFC class. For example, an entity instance which is an IfcWall class will have a Name attribute, and an IfcColourRgb will have a Red attribute. Please consult the buildingSMART official documentation.

Example:

model = ifcopenshell.open(file_path)
walls = model.by_type("IfcWall")
wall = walls[0]

print(wall) # #38=IFCWALL('2MEinnTPbCMwLOgceaQZFu',$,$,'My Wall',$,#52,#47,$,$);
print(wall.is_a()) # IfcWall

# Note: the `Name` attribute is dynamic, based on the IFC class.
print(wall.Name) # My Wall

# Attributes are ordered and may also be accessed via index.
print(wall[3]) # My Wall

print(wall.__class__) # <class 'ifcopenshell.entity_instance'>
Parameters:

e – Wrapper’s entity_instance or a tuple (schema_identifier, ifc_class).

attribute_name(attr_idx: int) str

Return the name of a positional attribute of the element

Parameters:

attr_idx – The index of the attribute

attribute_type(attr: int | str) str

Return the data type of a positional attribute of the element

Parameters:

attr – The index or name of the attribute

compare(other, op, reverse=False)

Compares with another instance.

For simple types the declaration name is not taken into account:

>>> f = ifcopenshell.file()
>>> f.createIfcInteger(0) < f.createIfcPositiveInteger(1)
True

For entity types the declaration name is taken into account:

>>> f.createIfcWall('a') < f.createIfcWall('b')
True
>>> f.createIfcWallStandardCase('a') < f.createIfcWall('b')
False

Comparing simple types with different underlying types throws an exception:

>>> f.createIfcInteger(0) < f.createIfcLabel('x')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "entity_instance.py", line 371, in compare
    return op(a, b)
TypeError: '<' not supported between instances of 'int' and 'str'
Args:

other (_type_): Right hand side (or lhs when reverse = True) op (_type_): The comparison operator (likely from the operator module) reverse (bool, optional): When true swaps lhs and rhs. Defaults to False.

Returns:

bool: The comparison predicate applied to self and other

get_info(include_identifier: bool = True, recursive: bool = False, return_type: type[dict] | type = dict, ignore: collections.abc.Sequence[str] = (), scalar_only: bool = False) dict[str, Any]

Return a dictionary of the entity_instance’s properties (Python and IFC) and their values.

Resulting dictionary keys: ‘id’, ‘type’, all entity attribute names.

Parameters:
  • include_identifier – Whether or not to include the STEP numerical identifier

  • recursive – Whether or not to convert referenced IFC elements into dictionaries too. All attributes also apply recursively

  • return_type – The return data type to be casted into

  • ignore – A list of attribute names to ignore

  • scalar_only – Filters out all values that are IFC instances

Returns:

A dictionary of properties and their corresponding values

Example:

ifc_file = ifcopenshell.open(file_path)
products = ifc_file.by_type("IfcProduct")
obj_info = products[0].get_info()
print(obj_info.keys())
>>> dict_keys(['Description', 'Name', 'BuildingAddress', 'LongName', 'GlobalId', 'ObjectPlacement', 'OwnerHistory', 'ObjectType',
>>> ...'ElevationOfTerrain', 'CompositionType', 'id', 'Representation', 'type', 'ElevationOfRefHeight'])
get_info_2(include_identifier: bool = True, recursive: bool = False, return_type: type[dict] = dict, ignore: collections.abc.Sequence[str] = ()) dict[str, Any]

More perfomant version of .get_info() but with limited arguments values.

Method has exactly the same signature as .get_info() but it doesn’t support getting information non-recursively.

Currently supported arguments values:
  • recursive: True (will fail with default False value from .get_info())

  • return_type: dict

  • ignore: () (empty tuple)

id() int

Return the STEP numerical identifier

is_a() str
is_a(ifc_class: str) bool
is_a(with_schema: bool) str

Return the IFC class name of an instance, or checks if an instance belongs to a class.

The check will also return true if a parent class name is provided.

Parameters:

args – If specified, is a case insensitive IFC class name to check or if specified as a boolean then will define whether returned IFC class name should include schema name (e.g. “IFC4.IfcWall” if True and “IfcWall” if False). If omitted will act as False.

Returns:

Either the name of the class, or a boolean if it passes the check

Example:

f = ifcopenshell.file()
f.create_entity('IfcPerson')
f.is_a()
>>> 'IfcPerson'
f.is_a('IfcPerson')
>>> True
is_entity() bool

Tests whether the instance is an entity type as opposed to a simple data type.

Returns:

bool: True if the instance is an entity

to_string(valid_spf=True) str

Returns a string representation of the current entity instance. Equal to str(self) when valid_spf=False. When valid_spf is True returns a representation of the string that conforms to valid Step Physical File notation. The difference being entity names in upper case and string attribute values with unicode values encoded per the specific control directives.

static unwrap_value(v)
static walk(f: collections.abc.Callable[[Any], bool], g: collections.abc.Callable[[Any], Any], value: Any) Any

Applies a transformation to value based on a given condition.

If value is a nested structure (e.g., a list or a tuple) will apply transformation to it’s elements.

Parameters:
  • f – A callable that takes a single argument and returns a boolean value. It represents the condition.

  • g – A callable that takes a single argument and returns a transformed value. It represents the transformation.

  • value – Any object, the input value to be processed

Returns:

Transformed value

Example:

# Define condition and transformation functions
condition = lambda v: v == old
transform = lambda v: new

# Usage example
attribute_value = element.RelatedElements
print(old in attribute_value, new in attribute_value) # True, False

result = element.walk(condition, transform, element.RelatedElements)
print(old in attribute_value, new in attribute_value) # False, True
static wrap_value(v, file: ifcopenshell.file)
property file
method_list: MethodList | None = None
wrapped_data: ifcopenshell.ifcopenshell_wrapper.entity_instance
class ifcopenshell.file(f: ifcopenshell.ifcopenshell_wrapper.file | None = None, schema: ifcopenshell.util.schema.IFC_SCHEMA | None = None, schema_version: tuple[int, int, int, int] | None = None)

Base class for containing IFC files.

Class has instance methods for filtering by element Id, Type, etc. Instantiated objects can be subscripted by Id or Guid

Example:

model = ifcopenshell.open(file_path)
products = model.by_type("IfcProduct")
print(products[0].id(), products[0].GlobalId) # 122 2XQ$n5SLP5MBLyL442paFx
print(products[0] == model[122] == model["2XQ$n5SLP5MBLyL442paFx"]) # True

Create a new blank IFC model

This IFC model does not have any entities in it yet. See the create_entity function for how to create new entities. All data is stored in memory. If you wish to write the IFC model to disk, see the write function.

Parameters:
  • f – The underlying IfcOpenShell file object to be wrapped. This is an internal implementation detail and should generally be left as None by users.

  • schema – Which IFC schema to use, chosen from “IFC2X3”, “IFC4”, or “IFC4X3”. These refer to the ISO approved versions of IFC. Defaults to “IFC4” if not specified, which is currently recommended for all new projects.

  • schema_version – If you want to specify an exact version of IFC that may not be an ISO approved version, use this argument instead of schema. IFC versions on technical.buildingsmart.org are described using 4 integers representing the major, minor, addendum, and corrigendum number. For example, (4, 0, 2, 1) refers to IFC4 ADD2 TC1, which is the official version approved by ISO when people refer to “IFC4”. Generally you should not use this argument unless you are testing non-ISO IFC releases.

Example:

# Create a new IFC4 model, create a wall, then save it to an IFC-SPF file.
model = ifcopenshell.file()
model.create_entity("IfcWall")
model.write("/path/to/model.ifc")

# Create a new IFC4X3 model
model = ifcopenshell.file(schema="IFC4X3")

# A poweruser testing out a particular version of IFC4X3
model = ifcopenshell.file(schema_version=(4, 3, 0, 1))
add(inst: ifcopenshell.entity_instance, _id: int = None) ifcopenshell.entity_instance

Adds an entity including any dependent entities to an IFC file. If the entity already exists, it is not re-added. Existence of entity is checked by it’s .identity().

Parameters:

inst – The entity instance to add

Returns:

An ifcopenshell.entity_instance

assign_header_from(other: ifcopenshell.file) None
batch()

Low-level mechanism to speed up deletion of large subgraphs

begin_transaction() None
by_guid(guid: str) ifcopenshell.entity_instance

Return an IFC entity instance filtered by IFC GUID.

Parameters:

guid – GlobalId value in 22-character encoded form

Raises:

RuntimeError – If guid is not found.

Returns:

An ifcopenshell.entity_instance

by_id(id: int) ifcopenshell.entity_instance

Return an IFC entity instance filtered by IFC ID.

Parameters:

id – STEP numerical identifier

Raises:

RuntimeError – If id is not found.

Returns:

An ifcopenshell.entity_instance

by_type(type: str, include_subtypes=True) list[ifcopenshell.entity_instance]

Return IFC objects filtered by IFC Type and wrapped with the entity_instance class.

If an IFC type class has subclasses, all entities of those subclasses are also returned.

Parameters:
  • type – The case insensitive type of IFC class to return.

  • include_subtypes – Whether or not to return subtypes of the IFC class

Raises:

RuntimeError – If type is not found in IFC schema.

Returns:

A list of ifcopenshell.entity_instance objects

create_entity(type: str, *args: Any, **kwargs: Any) ifcopenshell.entity_instance

Create a new IFC entity in the file.

You can also use dynamic methods similar to ifc_file.createIfcWall(…) to create IFC entities. They work exactly the same as if you would do ifc_file.create_entity(“IfcWall”, …) but the resulting typing is not as accurate as for create_entity due to a dynamic nature of those methods.

Parameters:
  • type – Case insensitive name of the IFC class

  • args – The positional arguments of the IFC class

  • kwargs – The keyword arguments of the IFC class

Returns:

An entity instance

Example:

f = ifcopenshell.file()
f.create_entity("IfcPerson")
# >>> #1=IfcPerson($,$,$,$,$,$,$,$)
f.create_entity("IfcPerson", "Foobar")
# >>> #2=IfcPerson('Foobar',$,$,$,$,$,$,$)
f.create_entity("IfcPerson", Identification="Foobar")
# >>> #3=IfcPerson('Foobar',$,$,$,$,$,$,$)
discard_transaction() None
end_transaction() None
static from_pointer(address: int) file
static from_string(s: str) file
get_inverse(inst: ifcopenshell.entity_instance, allow_duplicate: Literal[False] = False, with_attribute_indices: bool = False) set[ifcopenshell.entity_instance]
get_inverse(inst: ifcopenshell.entity_instance, allow_duplicate: Literal[True], with_attribute_indices: bool = False) list[ifcopenshell.entity_instance]
get_inverse(inst: ifcopenshell.entity_instance, allow_duplicate: bool, with_attribute_indices: bool = False) list[ifcopenshell.entity_instance] | set[ifcopenshell.entity_instance]

Return a list of entities that reference this entity

Warning: this is a slow function, especially when there is a large number of inverses (such as for a shared owner history). If you are only interested in the total number of inverses (typically 0, 1, or N), consider using get_total_inverses().

Parameters:
  • inst – The entity instance to get inverse relationships

  • allow_duplicate – Returns a list when True, set when False

  • with_attribute_indices – Returns pairs of <i, idx> where i[idx] is inst or contains inst. Requires allow_duplicate=True

Returns:

A list or set of ifcopenshell.entity_instance objects.

get_total_inverses(inst: ifcopenshell.entity_instance) int

Returns the number of entities that reference this entity

This is equivalent to len(model.get_inverse(element)), but significantly faster.

Parameters:

inst – The entity instance to get inverse relationships

Returns:

The total number of references

redo() None
remove(inst: ifcopenshell.entity_instance) None

Deletes an IFC object in the file.

Attribute values in other entity instances that reference the deleted object will be set to null. In the case of a list or set of references, the reference to the deleted will be removed from the aggregate.

Parameters:

inst – The entity instance to delete

set_history_size(size: int) None
to_string() str
traverse(inst: ifcopenshell.entity_instance, max_levels: int | None = None, breadth_first: bool = False) list[ifcopenshell.entity_instance]

Get a list of all referenced instances for a particular instance including itself

Parameters:
  • inst – The entity instance to get all sub instances

  • max_levels – How far deep to recursively fetch sub instances. None or -1 means infinite.

  • breadth_first – Whether to use breadth-first search, the default is depth-first.

Returns:

A list of ifcopenshell.entity_instance objects

unbatch()

Low-level mechanism to speed up deletion of large subgraphs

undo() None
write(path: os.PathLike | str, format: str | None = None, zipped: bool = False) None

Write ifc model to file.

:param format: Force use of a specific format. Guessed from file name

if None. Supported formats : .ifc, .ifcXML, .ifcZIP (equivalent to format=”.ifc” with zipped=True) For zipped .ifcXML use format=”.ifcXML” with zipped=True

:param zipped: zip the file after it is written

Example:

model.write("path/to/model.ifc")
model.write("path/to/model.ifcXML")
model.write("path/to/model.ifcZIP")
model.write("path/to/model.ifcZIP", format=".ifcXML", zipped=True)
model.write("path/to/model.anyextension", format=".ifcXML")
future: list[Transaction]

Reversed chronological order - from newest to oldest.

header: ifcopenshell.ifcopenshell_wrapper.IfcSpfHeader
history: list[Transaction]

Chronological order - from oldest to newest.

history_size: int = 64
property mvd
property schema: ifcopenshell.util.schema.IFC_SCHEMA

General IFC schema version: IFC2X3, IFC4, IFC4X3.

property schema_identifier: str

Full IFC schema version: IFC2X3_TC1, IFC4_ADD2, IFC4X3_ADD2, etc.

property schema_version: tuple[int, int, int, int]

Numeric representation of the full IFC schema version.

E.g. IFC4X3_ADD2 is represented as (4, 3, 2, 0).

to_delete: set[ifcopenshell.entity_instance] | None = None

Entities for batch removal.

transaction: Transaction | None = None
units: dict[str, ifcopenshell.entity_instance.entity_instance]
wrapped_data: ifcopenshell.ifcopenshell_wrapper.file
class ifcopenshell.sqlite(filepath: str)

Bases: ifcopenshell.file.file

Base class for containing IFC files.

Class has instance methods for filtering by element Id, Type, etc. Instantiated objects can be subscripted by Id or Guid

Example:

model = ifcopenshell.open(file_path)
products = model.by_type("IfcProduct")
print(products[0].id(), products[0].GlobalId) # 122 2XQ$n5SLP5MBLyL442paFx
print(products[0] == model[122] == model["2XQ$n5SLP5MBLyL442paFx"]) # True

Open existing sqlite IFC database.

To create a new database from IFC file consider using Ifc2Sql IfcPatch:

https://docs.ifcopenshell.org/autoapi/ifcpatch/recipes/Ifc2Sql/index.html

Parameters:

filepath – Path to sqlite database.

by_id(id: int) sqlite_entity | None

Return an IFC entity instance filtered by IFC ID.

Parameters:

id – STEP numerical identifier

Raises:

RuntimeError – If id is not found.

Returns:

An ifcopenshell.entity_instance

by_type(type: str, include_subtypes: bool = True) list[sqlite_entity]

Return IFC objects filtered by IFC Type and wrapped with the entity_instance class.

If an IFC type class has subclasses, all entities of those subclasses are also returned.

Parameters:
  • type – The case insensitive type of IFC class to return.

  • include_subtypes – Whether or not to return subtypes of the IFC class

Raises:

RuntimeError – If type is not found in IFC schema.

Returns:

A list of ifcopenshell.entity_instance objects

clear_cache() None
create_entity(type, *args, **kawrgs) NoReturn

Not supported for sqlite database.

get_geometry(ids: list[int]) dict[str, dict]
get_inverse(inst: sqlite_entity, allow_duplicate: bool = False, with_attribute_indices: bool = False) set[sqlite_entity]

Return a list of entities that reference this entity

Warning: this is a slow function, especially when there is a large number of inverses (such as for a shared owner history). If you are only interested in the total number of inverses (typically 0, 1, or N), consider using get_total_inverses().

Parameters:
  • inst – The entity instance to get inverse relationships

  • allow_duplicate – Returns a list when True, set when False

  • with_attribute_indices – Returns pairs of <i, idx> where i[idx] is inst or contains inst. Requires allow_duplicate=True

Returns:

A list or set of ifcopenshell.entity_instance objects.

is_entity_list(attribute: ifcopenshell.ifcopenshell_wrapper.attribute) bool
preprocess_schema() None
traverse(inst: sqlite_entity, max_levels: int | None = None, breadth_first: bool = False) list[sqlite_entity]

Get a list of all referenced instances for a particular instance including itself

Parameters:
  • inst – The entity instance to get all sub instances

  • max_levels – How far deep to recursively fetch sub instances. None or -1 means infinite.

  • breadth_first – Whether to use breadth-first search, the default is depth-first.

Returns:

A list of ifcopenshell.entity_instance objects

class_map: dict[str, list[int]]
cursor
db
entity_cache: dict[int, sqlite_entity]
filepath
future = []

Reversed chronological order - from newest to oldest.

history = []

Chronological order - from oldest to newest.

history_size = 64
id_map: dict[int, str]
ifc_schema
schema: ifcopenshell.util.schema.IFC_SCHEMA = 'IFC4'

General IFC schema version: IFC2X3, IFC4, IFC4X3.

transaction = None
wrapped_data = None
class ifcopenshell.sqlite_entity(id: int, ifc_class: str, file: sqlite = None)

Bases: ifcopenshell.entity_instance.entity_instance

Represents an entity (wall, slab, property, etc) of an IFC model

An IFC model consists of entities. Examples of entities include walls, slabs, doors and so on. Entities can also be non-physical things, like properties, systems, construction tasks, colours, geometry, and more.

Entities are defined through an IFC Class. There are hundreds of IFC Classes defined as part of the ISO standard by the buildingSMART International organisation. The IFC Class defines the attributes of an entity, as well as the data types and whether or not an attribute is mandatory or optional.

IfcOpenShell’s API dynamically implements the IFC schema. You will not find documentation about available IFC Classes, or what attributes they have. Please consult the buildingSMART official documentation or start reading Introduction to IFC.

In addition to the Python methods you see documented here, an instantiated entity_instance will have attributes defined by its IFC class. For example, an entity instance which is an IfcWall class will have a Name attribute, and an IfcColourRgb will have a Red attribute. Please consult the buildingSMART official documentation.

Example:

model = ifcopenshell.open(file_path)
walls = model.by_type("IfcWall")
wall = walls[0]

print(wall) # #38=IFCWALL('2MEinnTPbCMwLOgceaQZFu',$,$,'My Wall',$,#52,#47,$,$);
print(wall.is_a()) # IfcWall

# Note: the `Name` attribute is dynamic, based on the IFC class.
print(wall.Name) # My Wall

# Attributes are ordered and may also be accessed via index.
print(wall[3]) # My Wall

print(wall.__class__) # <class 'ifcopenshell.entity_instance'>
Parameters:

e – Wrapper’s entity_instance or a tuple (schema_identifier, ifc_class).

get_info(include_identifier=True, recursive=False, return_type=dict, ignore=(), scalar_only=False) dict[str, Any]

Return a dictionary of the entity_instance’s properties (Python and IFC) and their values.

Resulting dictionary keys: ‘id’, ‘type’, all entity attribute names.

Parameters:
  • include_identifier – Whether or not to include the STEP numerical identifier

  • recursive – Whether or not to convert referenced IFC elements into dictionaries too. All attributes also apply recursively

  • return_type – The return data type to be casted into

  • ignore – A list of attribute names to ignore

  • scalar_only – Filters out all values that are IFC instances

Returns:

A dictionary of properties and their corresponding values

Example:

ifc_file = ifcopenshell.open(file_path)
products = ifc_file.by_type("IfcProduct")
obj_info = products[0].get_info()
print(obj_info.keys())
>>> dict_keys(['Description', 'Name', 'BuildingAddress', 'LongName', 'GlobalId', 'ObjectPlacement', 'OwnerHistory', 'ObjectType',
>>> ...'ElevationOfTerrain', 'CompositionType', 'id', 'Representation', 'type', 'ElevationOfRefHeight'])
id() int

Return the STEP numerical identifier

unserialise_value(value)
sqlite_wrapper: sqlite_entity.sqlite_wrapper