Molior IFC model builder

Molior builds 3D models from topologist ‘traces’ and ‘hulls’

Which traces and hulls are used, and how they are used, are defined by files in the ‘share’ folder and subfolders. Access to these style definitions is handled by the .style module.

Molior uses IfcOpenShell to generate IFC models of buildings, with some extra helper methods defined in the .ifc module. Different building parts need to be constructed differently, so walls, floors, extrusions etc. are each handled by dedicated modules.

Molior is largely derived from the Perl ‘Molior’ module, but has been rewritten in python in order to interface with Topologic and IfcOpenShell.

class molior.Molior(**args)

A Builder, has resources to build

build_hull(stylename='default', condition='panel', hull=<topologist.ushell.shell object>)

Generates IFC data for a single hull and adds to the current building

build_trace(stylename='default', condition='external', elevation=0.0, height=2.7, chain=<topologist.ugraph.graph object>)

Generates IFC data for a single trace and adds to the current building

connect_assemblies()

Assign parents to entities tagged with Topologic indexes

connect_spaces()

Given objects and boundaries are tagged with Topologic indexes, assign them to correct spaces

connect_structure()

Given Structural Member entities are tagged with Topologic indexes, connect them

execute()

Iterate through ‘traces’ and ‘hulls’ and populate an ifc ‘file’ object

classmethod from_cellcomplex(file=None, cellcomplex=None, name='My Building', share_dir='share')

Create a Molior object from a tagged CellComplex

classmethod from_faces_and_widgets(file=None, faces=[], widgets=[], name='My Building', share_dir='share')

Create a Molior object from lists of Topologic Faces and widgets.

classmethod from_topology(file=None, topology=None, name='My Building', share_dir='share')

Create a Molior object from a tagged Topology

classmethod get_cellcomplex_from_ifc(entity)

Retrieve a CellComplex definition stored by the stash_topology() method

init_building()

Create and relate Site, Building and Storey Spatial Element products, set as current building

stash_topology()

Represent a Topologic model as IFC geometry

Abstract Classes

class molior.baseclass.BaseClass(args=None)

A generic building object

add_psets(product)

self.psets is a dictionary of Psets, add them to an Ifc product

class molior.baseclass.TraceClass(args=None)

A building object that follows a path

angle_segment(index)

Angle of segment, degrees anticlockwise from ‘east’

clipping_plane(index)

A plane defined by x, y & z directions and a point on the plane

corner_coor(index)

2D coordinates of a corner

corner_in(index)

offset inside corner

corner_offset(index, distance)

2D coordinates of a corner offset by an arbitrary distance

corner_out(index)

offset outside corner

direction_segment(index)

Normalised 2D direction vector of segment

extension_end()

extend the end of an open path

extension_start()

extend the start of an open path

length_segment(index)

Distance between vertices of this segment

normal_segment(index)

2D normal right-hand side

segments()

Number of segments in the path taking account for being closed or not

Space

class molior.space.Space(args=None)

A room or outside volume, as a 2D path extruded vertically

execute()

Generate some ifc

Wall

class molior.wall.Wall(args=None)

A vertical wall, internal or external

align_openings(id_segment)

equally space openings along the wall

border(id_segment)

set border distances if inside corners

execute()

Generate some ifc

fix_gable(id_segment)

Shorten or delete openings that project above roofline

fix_heights(id_segment)

Top of openings need to be lower than ceiling soffit

fix_overlaps(id_segment)

openings don’t want to overlap with each other

fix_overrun(id_segment)

openings can’t go past the end of the segment

fix_underrun(id_segment)

openings can’t start before beginning of segment

get_family(usage)

Retrieve an family definition via the style

init_openings()

We need an array for openings the same size as wall segments array

length_openings(id_segment)

minimum wall length the currently defined openings require

opening_coor(id_segment, id_opening)

rectangle coordinates of an opening on the axis

populate_exterior_openings(id_segment, interior_type, access)

Add initial windows and doors to a segment

populate_interior_openings(id_segment, type_a, type_b, access)

Add an initial door to an interior segment

Extrusion

class molior.extrusion.Extrusion(args=None)

A profile following a horizontal 2D path

execute()

Generate some ifc

Floor

class molior.floor.Floor(args=None)

A floor filling a room or space

execute()

Generate some ifc

Repeat

class molior.repeat.Repeat(args=None)

A row of evenly spaced identical objects

execute()

Generate some ifc

Stair

class molior.stair.Stair(args=None)

a stair filling a single storey extruded space

execute()

Generate some ifc

Shell

class molior.shell.Shell(args=None)

A pitched roof or soffit

execute()

Generate some ifc

Grillage

class molior.grillage.Grillage(args=None)

planar feature consisting of repeated linear elements

execute()

Generate some ifc

Geometry helpers

molior.geometry.inset_path(vertices, inset=0.0)

insets an anticlockwise path

molior.geometry.map_to_2d(vertices, normal_vector)

Transform 3d nodes and their normal to 2d nodes, a return matrix and a vertical vector

molior.geometry.map_to_2d_simple(vertices, normal)

Transform 3d nodes and their normal to 2d nodes and a return matrix

molior.geometry.matrix_align(A, B)

A transform matrix that moves to A and 2D rotates to align the X axis to B

molior.geometry.matrix_transform(theta, coor)

A transform matrix from a rotation in the XY plane and an XYZ shift

molior.geometry.normal_by_perimeter(vertices)

assuming set of vertices represent a planar face, calculate normal

molior.geometry.transform(matrix, A)

Transform a 2d or 3d vector using a 4x4 matrix

IFC helpers

Domain-specific extensions to IfcOpenShell

A collection of code for commonly used IFC related tasks

molior.ifc.add_cell_topology_epsets(self: ifcopenshell.file, entity: entity_instance, cell: Any | None) None

Add topology-related property sets to a cell-based entity.

Args:

self: The IFC file. entity: The entity to add properties to. cell: The topological cell, which may have properties like index and usage.

molior.ifc.add_face_topology_epsets(self: ifcopenshell.file, entity: entity_instance, face: Any | None, back_cell: Any | None, front_cell: Any | None) None

Add topology-related property sets to a face-based entity.

Args:

self: The IFC file. entity: The entity to add properties to. face: The topological face, which may have properties like index and style. back_cell: The cell behind the face. front_cell: The cell in front of the face.

molior.ifc.add_pset(self: ifcopenshell.file, product: entity_instance, name: str, properties: Dict[str, Any]) None

Helper method to add an Ifc PropertySet.

Args:

self: The IFC file. product: The product to add the property set to. name: The name of the property set. properties: A dictionary of property names and values.

molior.ifc.assign_space_byindex(self: ifcopenshell.file, entity: entity_instance, building: entity_instance, index: int | str) None

Assign object to a Space by index.

Args:

self: The IFC file. entity: The entity to assign to a space. building: The building containing the spaces. index: The index of the space to assign to, matching the CellIndex in EPset_Topology.

molior.ifc.assign_storey_byindex(self: ifcopenshell.file, entity: entity_instance, building: entity_instance, index: int | str) entity_instance

Assign object to a storey by index.

Args:

self: The IFC file. entity: The entity to assign to a storey. building: The building containing the storeys. index: The index or name of the storey to assign to.

Returns:

The storey that the entity was assigned to.

molior.ifc.clip_solid(self: ifcopenshell.file, solid: entity_instance, start: List[float], end: List[float], element: entity_instance | None = None) entity_instance

Clip a wall using a half-space solid.

Args:

self: The IFC file. solid: The solid to be clipped. start: The start point of the clipping plane. end: The end point of the clipping plane. element: If provided, registers the clipping in the element’s

BBIM_Boolean pset so Bonsai preserves it on regeneration.

Returns:

An IfcBooleanClippingResult entity.

molior.ifc.create_closed_profile_from_points(self: ifcopenshell.file, points: List[List[float]]) entity_instance

Creates a closed 2D profile from list of 2D points.

Args:

self: The IFC file. points: A list of 2D points as [x, y] coordinates that define the profile outline.

The first and last points should match to create a closed loop.

Returns:

An IfcArbitraryClosedProfileDef entity.

molior.ifc.create_default_contexts(self: ifcopenshell.file) None

Creates a standard set of representation contexts for the IFC model.

This function establishes a comprehensive set of geometric representation contexts for different views and purposes within the IFC model.

Args:

self: The IFC file where contexts should be created.

molior.ifc.create_extruded_area_solid(self: ifcopenshell.file, points: List[List[float]], height: float, direction: List[float] = [0.0, 0.0, 1.0]) entity_instance

A simple vertically extruded profile.

Args:

self: The IFC file. points: A list of 2D points defining the profile to extrude. height: The extrusion height. direction: The direction vector for extrusion (default: upward in Z-axis).

Returns:

An IfcExtrudedAreaSolid entity.

molior.ifc.create_extruded_area_solid2(self: ifcopenshell.file, material_profile: entity_instance, start: List[float], direction: List[float], length: float) entity_instance

Create an extruded solid from a material profile, with specific orientation.

Args:

self: The IFC file. material_profile: The material profile containing the profile to extrude. start: The starting point [x, y, z] for the extrusion. direction: The direction vector for the extrusion axis. length: The length of extrusion.

Returns:

An IfcExtrudedAreaSolid entity.

molior.ifc.create_face_surface(self: ifcopenshell.file, polygon: List[List[float]], normal: List[float]) entity_instance

Create a single-face shape.

Args:

self: The IFC file. polygon: A list of 3D points defining the vertices of the face. normal: The normal vector of the face.

Returns:

An IfcFaceSurface entity.

molior.ifc.create_storeys(self: ifcopenshell.file, parent: entity_instance, elevations: Dict[float, int]) None

Add Storey Spatial Elements to a Building.

Args:

self: The IFC file. parent: The parent building element to which storeys will be added. elevations: A dictionary mapping elevation heights (float) to storey numbers (int).

For example: {0.0: 0, 3.5: 1, 7.0: 2} for ground, first, and second floors.

molior.ifc.create_tessellation_from_mesh(self: ifcopenshell.file, vertices: List[List[float]], faces: List[List[int]]) entity_instance

Create a Tessellation from vertex coordinates and faces.

Args:

self: The IFC file. vertices: A list of 3D points defining the vertices of the mesh. faces: A list of lists of vertex indices defining the faces of the mesh.

Returns:

An IfcPolygonalFaceSet entity.

molior.ifc.create_tessellations_from_mesh_split(self: ifcopenshell.file, vertices: List[List[float]], faces: Dict[str, List[List[int]]]) List[entity_instance]

Create a Tessellation from vertex coordinates and split faces.

Args:

self: The IFC file. vertices: A list of 3D points defining the vertices of the mesh. faces: A dictionary mapping style names to lists of face vertex indices.

Returns:

A list of IfcPolygonalFaceSet entities with associated styles.

molior.ifc.delete_ifc_product(self: ifcopenshell.file, product: entity_instance | None) None

Recursively delete a product and its children.

This function traverses the relationships of the product to find and delete all related objects, ensuring clean removal without orphaned references.

Args:

self: The IFC file. product: The product to delete, or None (in which case no action is taken).

molior.ifc.get_building_by_name(self: ifcopenshell.file, parent: entity_instance, name: str) entity_instance

Add a Building to a Site, or retrieve if already there.

Args:

self: The IFC file. parent: The parent site to which the building belongs. name: The name of the building to find or create.

Returns:

The existing or newly created building entity.

molior.ifc.get_context(ifc_file: ifcopenshell.file, context: str | None = None, subcontext: str | None = None, target_view: str | None = None) entity_instance | None

Retrieve a geometric representation context from the IFC file.

Args:

ifc_file: The IFC file to search in. context: The top-level context type (e.g., “Model”, “Plan”). subcontext: The subcontext identifier (e.g., “Body”, “Axis”). target_view: The target view (e.g., “MODEL_VIEW”, “PLAN_VIEW”).

Returns:

The matching context entity, or None if not found.

molior.ifc.get_context_by_name(self: ifcopenshell.file, parent_context_identifier: str | None = None, context_identifier: str | None = None, target_view: str | None = None) entity_instance

Retrieve or create a Representation Context in the IFC model.

This function locates an existing context or creates a new one based on the provided parameters.

Args:

self: The IFC file where the context should be found or created. parent_context_identifier: The identifier of the parent context (e.g., “Model” or “Plan”). context_identifier: The identifier of the context to retrieve or create (e.g., “Body”, “Axis”). target_view: The target view for the context (e.g., “MODEL_VIEW”, “PLAN_VIEW”).

Returns:

The retrieved or newly created context entity.

molior.ifc.get_library_by_name(self: ifcopenshell.file, library_name: str) entity_instance

Retrieve a Project Library by name, creating it if necessary.

Args:

self: The IFC file. library_name: The name of the library to find or create.

Returns:

The existing or newly created project library entity.

molior.ifc.get_material_by_name(self: ifcopenshell.file, style_object: Any, stylename: str = 'default', name: str = 'Error') entity_instance

Retrieve an IfcMaterial by name, creating it if necessary.

Args:

self: The IFC file. style_object: The style manager object that provides library access. stylename: The name of the style collection to search in. name: The name of the material to find or create.

Returns:

The existing or newly created material entity.

molior.ifc.get_parent_building(entity: entity_instance) entity_instance | None

Retrieve whatever Building contains this entity, or None.

This function traverses the IFC relationship hierarchy to find the building that contains the given entity.

Args:

entity: The IFC entity to find the containing building for.

Returns:

The parent building entity, or None if not found.

molior.ifc.get_site_by_name(self: ifcopenshell.file, parent: entity_instance, name: str) entity_instance

Add a Site to a Project, or retrieve if already there.

Args:

self: The IFC file. parent: The parent project to which the site belongs. name: The name of the site to find or create.

Returns:

The existing or newly created site entity.

molior.ifc.get_structural_analysis_model_by_name(self: ifcopenshell.file, spatial_element: entity_instance, name: str) entity_instance

Add a structural model to a building, or retrieve if already there.

Args:

self: The IFC file. spatial_element: The building or other spatial element the structural model services. name: The name for the structural model.

Returns:

The existing or newly created structural analysis model entity.

molior.ifc.get_thickness(self: ifcopenshell.file, product: entity_instance) float

Gets total thickness for extruded products and types.

For products with associated material layer sets, calculates the total thickness by summing the thicknesses of all layers.

Args:

self: The IFC file. product: The product to calculate thickness for.

Returns:

The total thickness as a float.

molior.ifc.get_type_object(self: ifcopenshell.file, style_object: Any, ifc_type: str = 'IfcBuildingElementProxyType', stylename: str = 'default', name: str = 'error') entity_instance

Fetch a Type Object locally, or from an external IFC library.

Args:

self: The IFC file. style_object: The style manager object that provides library access. ifc_type: The IFC class type to create or retrieve. stylename: The name of the style collection to search in. name: The name of the type object to find or create.

Returns:

The existing or newly created type object entity.

molior.ifc.init(name: str = 'Homemaker Project', file: ifcopenshell.file | None = None) ifcopenshell.file

Creates and sets up an IFC ‘file’ object with basic project structure.

Args:

name: The name to give to the IFC project. file: An existing IFC file to use. If None, creates a new file.

Returns:

The initialized IFC file with project, person, organization, and units.

molior.ifc.purge_unused(self: ifcopenshell.file) None

Delete unused entities from the IFC file.

This function identifies and removes various types of unused entities that might remain in the model after other operations, such as property sets without references, placements without objects, etc.

Args:

self: The IFC file to clean up.

Molior Style system

A folder tree of inheritable style definitions and resources

A ‘style’ is defined by a collection of YAML configuration files and other file resources in a folder. This module provides methods for accessing this data.

Alternative styles are accessed by a stylename, each represented by a subfolder that inherits data and resources from all parent folders. For example, a style named ‘thin’ may be found in a folder named ${share_dir}/rustic/wood/thin; any query for ‘thin’ data not found in this folder will be sought in ${share_dir}/rustic/wood; failing that it will be sought in ${share_dir}/rustic, and finally in ${share_dir} itself.

Note that styles are accessed by their short stylename _not_ the path, this allows inheritance to be defined entirely by rearrangement of the configuration data. This also means that there may only be one folder called ‘thin’ in the folder tree, all others will be ignored.

class molior.style.Style(args=None)

Inheritable style definitions and resources

get(stylename)

retrieves a flattened style definition with ancestors filling in the gaps

get_from_library(stylename, ifc_class, name)

retrieves from Project Libraries in stylename folder or ancestors as necessary