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):

from viktor.parametrization import ViktorParametrization, GeometrySelectField


class Parametrization(ViktorParametrization):
selected_geometry = 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):

from viktor.parametrization import ViktorParametrization, GeometryMultiSelectField


class Parametrization(ViktorParametrization):
selected_geometries = 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:

from viktor.parametrization import ViktorParametrization, GeometrySelectField, DynamicArray, NumberField


class Parametrization(ViktorParametrization):
load_cases = DynamicArray("Load Cases")
load_cases.geometry = GeometrySelectField("Geometry")
load_cases.load = 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

from viktor import ViktorController
from viktor.parametrization import ViktorParametrization, GeometrySelectField, FileField
from viktor.views import IFCAndDataView, IFCAndDataResult, DataGroup, DataItem


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


class MyController(ViktorController):
label = 'My Entity Type'
parametrization = Parametrization

@IFCAndDataView("IFC", duration_guess=1, 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(DataItem(k, v))
data_items.append(DataItem(key, '', subgroup=DataGroup(*sub_data_items)))

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