Skip to main content

Geometry selection

New in v14.10.0

The geometry selection fields, enable the user to select geometries in an IFCView or a GeometryView.

Select a geometry

The GeometrySelectField enables the user to select a single (sub-)geometry in a geometric view, which is returned in the params as an identifier (string):

import viktor as vkt


class Parametrization(vkt.Parametrization):
selected_geometry = vkt.GeometrySelectField("Select a geometry")

Select multiple geometries

The GeometryMultiSelectField enables the user to select multiple (sub-)geometries in a geometric view, which is returned in the params as a list of identifiers (list of strings):

import viktor as vkt


class Parametrization(vkt.Parametrization):
selected_geometries = vkt.GeometryMultiSelectField("Select geometries")

Select a geometry in a DynamicArray

The GeometrySelectField and GeometryMultiSelectField can be used in combination with a DynamicArray to allow an arbitrary number of geometries or group of geometries to be selected and assign or group these with additional parameters:

import viktor as vkt


class Parametrization(vkt.Parametrization):
load_cases = vkt.DynamicArray("Load Cases")
load_cases.geometry = vkt.GeometrySelectField("Geometry")
load_cases.load = vkt.NumberField("Load", suffix="N")

Example

To support geometry selection, the following parts need to be implemented in the app:

  1. Create an IFCView in the controller
  2. Create a GeometrySelectField or GeometryMultiSelectField in the parametrization
  3. Use the identifier retrieved from the params in subsequent calculations

An IFC-file contains unique identifiers per geometry feature.

import ifcopenshell
import ifcopenshell.util.element
from pathlib import Path
from tempfile import NamedTemporaryFile

import viktor as vkt


class Parametrization(vkt.Parametrization):
ifc = vkt.FileField("Please provide an IFC file")
selected_geometry = vkt.GeometrySelectField("Select a geometry")


class Controller(vkt.Controller):
parametrization = Parametrization

@vkt.IFCAndDataView("IFC", x_axis_to_right=True)
def get_ifc_and_data_view(self, params, **kwargs):
ifc_file = params.ifc.file
if params.selected_geometry: # If user has made a selection, add its properties to `data`

# parse your ifc file (e.g. with ifcopenshell as below)
with NamedTemporaryFile(suffix=".ifc", delete=False, mode="w") as temp_f:
temp_f.write(ifc_file.getvalue())

model = ifcopenshell.open(Path(temp_f.name))
elem = model.by_id(int(params.selected_geometry))

# See https://wiki.osarch.org/index.php?title=IFC_attributes_and_properties
# for a list of available IFC attributes and properties

data_items = []
for key, val in ifcopenshell.util.element.get_psets(elem).items():
sub_data_items = []
for k,v in val.items():
sub_data_items.append(vkt.DataItem(k, v))
data_items.append(vkt.DataItem(key, '', subgroup=vkt.DataGroup(*sub_data_items)))

data = vkt.DataGroup(*data_items)
else:
data = vkt.DataGroup(vkt.DataItem('No geometries selected', ''))
return vkt.IFCAndDataResult(ifc=ifc_file, data=data)