Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

319 Commits

Repository files navigation

Voxelization Toolkit

Voxelization Toolkit for (IFC) Building Models

Introduction

(Building) models are widely different depending on modeller, phase, intended use, software application and version. Conventional BRep and Mesh geometry libraries can have robustness issues coming from floating point rounding errors and tolerances. For these reasons we provide building model analysis functionality using voxels. Comprehensive analysis regardless of modelling choices is enabled by robustly discretizing the complete building model geometry. The integer math is robust and easy to understand.

Use cases

The toolkit presented here has been used for:

  • Reliably compute volume (e.g entire building volume above and under ground; quantity calculation for non-manifold element geometries)
  • Evacuation analysis (providing a length to nearest exit for every reachable place in the model; taking into account obstacles)
  • Building code compliance (e.g of space dimensions taking into account contained elements)
  • Safety analysis (by analysing reachable space and fall hazards)
  • Detection of exterior elements (by calculating interior volume using neighbour traversal)
  • Model conversion (e.g for acoustic analysis - eroding small elements - using PCA to export slanted surfaces derived from voxel grid)
  • ...

Examples

Three examples (including visualization) are elaborated in python code in ./python/voxec

Headroom height

Calculate headroom height in the model taking all geometric elements into account

Evacuation distance

Calculate distance to the exterior for any point in the model taking into account obstacles

Exterior elements

Geometricaly assess exterior elements on multi-aspect models as BIM authoring tools often have erroneous IsExternal properties specified.

Installation

The voxec(.exe) runtime interpreter can be installed using the Anaconda (conda) package manager from the ifcopenshell channel.

conda install -c conda-forge ifcopenshell=v0.7.0
conda install -c ifcopenshell voxelization_toolkit

Quick tutorial

  1. Perform the installation steps above
  2. Create a new empty folder with:
  3. cd to the directory in powershell/bash and run: voxec voxelfile.txt
  4. Observe an output is printed like below as the flow of the procedure defined in voxelfile.txt is executed.
[ ]
severity: notice
message: executing {statement}
time: 2024:10:25 14:36:43.283
statement:
text: file = parse("duplex.ifc")
[##### ]
severity: notice
message: executing {statement}
time: 2024:10:25 14:36:43.392
statement:
text: surfaces = create_geometry(file)
[########### ]
severity: notice
message: executing {statement}
time: 2024:10:25 14:36:44.575
statement:
text: slabs = create_geometry(file,include={"IfcSlab"})
  1. Now add a line in voxelfile.txt: export_point_cloud(outmost_voxels, "outmost_voxels.obj") (ensure the file ends with a newline)
  2. and rerun voxec.
  3. The exported file can now be visualized for example in Blender.

Usage

Recommended usage is using the voxec runtime interpreter, which takes an input "voxelfile" which describes a series of commands. The grammar of such as voxelfile is:

iden = alpha (alnum | '_')*
statement = iden '=' function_call
quoted_string = '"' (char - '"')* '"'
sequence = '{' quoted_string? (',' quoted_string)* '}'
value = strict_double | int_ | quoted_string | iden | sequence
function_arg = iden '=' value
function_args = function_arg? (',' function_arg)*
function_call = iden '(' function_args ')'
argument_list = iden? (',' iden)*
function_def = "function" iden '(' argument_list ')' statement* "return" iden
start = (statement | function_def)*

For example:

file = parse("duplex.ifc")
slabss = create_geometry(file, include={"IfcSlab"})
roofss = create_geometry(file, include={"IfcRoof"})
slabs = voxelize(slabss)
roofs = voxelize(roofss)
floors_surface = subtract(slabs, roofs)
floor_volume = volume2(floors_surface)
floors = union(floors_surface, floor_volume)
floors_surface = collapse(floors, 0, 0, -1)
num = count(floors_surface)

A list of available commands is provide below.

Available commands:

assert()

Asserts that a certain the voxel grid or integer value specified in input represents a count greater than zero.

namerequiredtype
inputYvoxels,integer

collapse()

Reduce the volume of components along the direction vector to 1. Useful to calculate floor area by eliminating the thickness of floor slabs. This is the reverse of extrusion.

namerequiredtype
inputYvoxels
dxYinteger,real
dyYinteger,real
dzYinteger,real
untilnvoxels
maxninteger

collapse_count()

Same as collapse() but return voxel grid of type uint32 with the number of collapsed voxels.

namerequiredtype
inputYvoxels
dxYinteger,real
dyYinteger,real
dzYinteger,real
untilnvoxels
maxninteger

component_foreach()

Apply a function to each connected component individually

namerequiredtype
inputYvoxels
functionYstring
argumentYstring

constant_like()

Return a constant voxel grid of type type with value value with the same dimensions as input.

namerequiredtype
inputYvoxels
valueYinteger
typenstring

copy()

Return a copy of input, optionally with a different type.

namerequiredtype
inputYvoxels
typenstring

count()

Count the number of non-zero voxels in input. This is information is present as meta-data on most voxel region types.

namerequiredtype
inputYvoxels

count_components()

Count the number of connected components in input.

namerequiredtype
inputYvoxels

count_neighbours()

Returns a new u32 grid with for every voxel the number of neighbours counted, with 6 or 26 for connectivity.

namerequiredtype
inputYvoxels
connectivityYinteger

create_geometry()

Create geometry from a set of IFC building model inputs (uses IfcOpenShell, result is a set of OpenCASCADE solids)

namerequiredtype
inputYifcfile
includensequence
excludensequence
optionalninteger
only_transparentninteger
only_opaqueninteger

describe_components()

Print information on the connected components in input. Writes JSON information to a new file in ouput_path.

namerequiredtype
output_pathYstring
inputYvoxels

describe_group_by()

Takes the component labels in groups and print information on the components selected by these individual labels in input. Writes JSON information to a new file in ouput_path.

namerequiredtype
output_pathYstring
inputYvoxels
groupsYvoxels
use_bitsninteger
conserve_memoryninteger
only_countsninteger

dump_surfaces()

Revoxelize input_surfaces and dump information to output_path when intersecting with input_voxels

namerequiredtype
input_voxelsYvoxels
input_surfacesYsurfaceset
output_pathYstring

dimensionality_estimate()

Use PCA to estimate the local dimensionality for individual voxels. The three eigen values that are returned in a new grid describe the degree of variance along the principal axes. When these eigenvalues are roughly equal the voxel van be considered part of a 3d component. If there is one eigenvalue considerably greater than the other two, it constitutes a part of 1d component. Etc.

For each individual voxel a neighbourhood consisting of voxels within a topological distance of max_depth voxels is formed. For voxels on the edge of a component this means an assymetric neighborhood is formed, because the neighborhood extends inwards into the component, but outwards there are no neighbours. This affects the distribution of eigenvalues. In order to get a more uniform distribution of eigenvalues within a component, the reposition=1 can be used, which first takes a neighborhood of max_depth voxels and then takes the mean of that to be the seed of a second neighborhood traversal of max_depth_2 voxels. This effectively moves the center of the neighborhood inwards.

namerequiredtype
inputYvoxels
max_depthninteger
max_depth_2ninteger
distance_2nreal
neighbourhood_sizeninteger
repositionninteger

export_csv()

Exports a voxel grid to CSV.

namerequiredtype
inputYvoxels
filenameYstring

export_ifc()

Exports a subset of the IFC model in input depending on the whether a revoxelization of input_surfaces (previously computed from input) intersects with input_voxels.

namerequiredtype
inputYifcfile
input_voxelsYvoxels
input_surfacesYsurfaceset
output_pathYstring

export_json()

Same as export_ifc(), but don't serialize a full IFC model but rather element identifiers.

namerequiredtype
inputYifcfile
input_voxelsYvoxels
input_surfacesYsurfaceset
output_pathYstring

export_point_cloud()

Similar to export_csv() but a different format.

namerequiredtype
inputYvoxels
filenameYstring

exterior()

Computes the exterior of input by starting traversal from a point outside of the bounding box of input.

namerequiredtype
inputYvoxels

fill_gaps()

Fills 1-sized holes in input.

namerequiredtype
inputYvoxels

fill_volume()

Fills the interior volume of the bounded region in input.

namerequiredtype
inputYvoxels

filter_attributes()

Filters the ifc elements in input based on attribute values. Use keyword arguments to specify attribute names and values.

namerequiredtype
inputYifcfile

filter_properties()

Filters the ifc elements in input based on property values. Use keyword arguments to specify property names and values.

namerequiredtype
inputYifcfile

free()

Frees storage associated with a voxel grid. Use with caution.

namerequiredtype
inputYvoxels

greater_than()

Returns a binary voxel grid where the uint32 values in input are greater than rhs.

namerequiredtype
inputYvoxels
rhsYinteger

halfspace()

Create a half space (size provided by input) based on the plane equation a b c d.

namerequiredtype
inputYvoxels
aYreal
bYreal
cYreal
dYreal

intersect()

Returns the intersection of a and b.

namerequiredtype
aYvoxels
bYvoxels
if_non_emptyninteger

invert()

Returns the inversion of input. Should only be used on binary voxel grids.

namerequiredtype
inputYvoxels

json_stats()

Writes json statistics of currently defined variables (potentially filtered by variables).

namerequiredtype
output_pathYstring
variablesnsequence

keep_components()

Keep only the connected components in input with size greater or equal to min_size.

namerequiredtype
inputYvoxels
min_sizeYinteger

keep_neighbours()

Keeps only voxels with the num_neighbours amount of neighbours. Connectivity should be 6 or 26.

namerequiredtype
inputYvoxels
num_neighboursYinteger
connectivityYinteger

less_than()

Returns a binary voxel grid where the uint32 values in input are less than rhs.

namerequiredtype
inputYvoxels
rhsYinteger

local_move()

Move the created IFC geometry along their local coordinate axis, can be used to create thicker volumes for doors or windows for example.

namerequiredtype
inputYsurfaceset
dxYreal
dyYreal
dzYreal
VOXELSIZEnreal

local_sweep()

Sweeps the created IFC geometry along their local coordinate axis, can be used to create thicker volumes for doors or windows for example.

namerequiredtype
inputYsurfaceset
dxYreal
dyYreal
dzYreal
VOXELSIZEnreal

mesh()

Create a OBJ triangle mesh from the voxel interior. When use_value is specified create interfaces between segments with different values. When with_components is specified numeric identifiers are assigned to the connected components.

namerequiredtype
inputYvoxels
filenameYstring
use_valueninteger
with_componentsninteger
groupsnvoxels
with_vertex_normalsninteger

normal_estimate()

Perform PCA normal estimatation on the voxel grid in input. max_depth specifies the topological connection threshold of the neighbours to incorporate in the PCA.

namerequiredtype
inputYvoxels
max_depthYinteger

offset()

Returns a new voxel grid where neighbours of voxels in input are set.

namerequiredtype
inputYvoxels

offset_xy()

Returns a new voxel grid where XY-neighbours of voxels in input are set.

namerequiredtype
inputYvoxels
dYinteger,real

outmost()

Returns the outmost (rightmost actually) connected component in input.

namerequiredtype
inputYvoxels

parse()

Parse the IFC building model using IfcOpenShell

namerequiredtype
inputYstring

plane()

Create a 1-thickness plane from the plane equation in a b c d.

namerequiredtype
inputYvoxels
aYreal
bYreal
cYreal
dYreal

print_components()

Print information on the connnected components in input.

namerequiredtype
inputYvoxels

print_values()

Print information on the values in input.

namerequiredtype
inputYvoxels

repeat_slice()

namerequiredtype
inputYvoxels
axisYinteger
locationYreal
repetitionsYinteger

resample()

Resample the voxel grid in input using an integer factor. Use negative values for downsampling.

namerequiredtype
inputYvoxels
factorYinteger

segment()

Apply segmentation using a voxel grid obtained from normal_estimate().

namerequiredtype
inputYvoxels
angular_tolerancenreal
max_curvaturenreal

set()

Set an individual voxel on grid in input.

namerequiredtype
xYinteger,real
yYinteger,real
zYinteger,real
inputnvoxels

shift()

Shift the voxels in input along the direction vector dx dy dz.

namerequiredtype
inputYvoxels
dxYinteger,real
dyYinteger,real
dzYinteger,real
untilnvoxels
maxninteger

subtract()

Subtract b from a.

namerequiredtype
aYvoxels
bYvoxels
if_non_emptyninteger

sweep()

Sweeps the voxels in input along the direction vector dx dy dz.

namerequiredtype
inputYvoxels
dxYinteger,real
dyYinteger,real
dzYinteger,real
untilnvoxels
maxninteger

traverse()

Perform traversal on the voxels in input starting from the selection in seed, optionally with along a maximum number of voxels in depth. Operates on 6 or 26 connectivity. Returns a binary voxel grid by default but can also return uint32, in which case, when using 26-connectedness, values are multiples of [10, 10 * sqrt(2), 10 * sqrt(3)].

namerequiredtype
inputYvoxels
seedYvoxels
depthninteger,real
connectednessninteger
typenstring

union()

Returns the union of a and b.

namerequiredtype
aYvoxels
bYvoxels
if_non_emptyninteger

volume()

DEPRECATED use volume2() Returns the bounded interior region of input.

namerequiredtype
inputYvoxels

volume2()

Returns the bounded interior region of input. Calculated as the inversal of the exterior.

namerequiredtype
inputYvoxels

voxelize()

Voxelizes the geometry obtained from an IFC input file. Use method='volume' to have individual element interiors filled (computationally more complex).

namerequiredtype
inputYsurfaceset
VOXELSIZEnreal
typenstring
methodnstring

zeros()

Return a new empty voxel grid filled with zeros, same size as input.

namerequiredtype
inputYvoxels

About

Voxelization Toolkit for (IFC) Building Models

Resources

Stars

91 stars

Watchers

10 watching

Forks

Releases

Packages

Used by

Contributors

Languages