# Snippet Wednesday - Using Trimesh for complex geometries 📐

Hey everyone,

For this week’s Snippet Wednesday I’d like to share something I’ve used multiple times in the past when I had to deal with complex geometric operations in a VIKTOR `GeometryView`.

## The goal

So, let’s say you want to do something out of the ordinary, for this example, let’s say I want to truncate (or slice) a sphere:

VIKTOR provides a Geometry toolbox out-of-the-box, which covers most use-cases. For more advanced features (such as slicing) we should use a dedicated package that is specifically developed to do geometric operations such as `trimesh`. This can then be exported to a `gltf` file to be rendered in a `GeometryView`.

## The solution

One possible library to build geometries is Trimesh.
Let’s start with building a spere using trimesh in a VIKTOR `GeometryView`:

### Creating the sphere

``````from trimesh.creation import icosphere
...

@GeometryView('Trimesh truncated sphere', duration_guess=1)
def create_truncated_sphere(self, params, **kwargs):
height = params.height

# create sphere mesh
``````

Next we can define a plane to slice the circle at, in this case obviously based on the height parameter set by the user. That plane can then be used to slice the original sphere mesh using the Trimesh function `slice_mesh_plane()`

### Slicing the sphere

``````from trimesh.creation import icosphere
from trimesh.intersections import slice_mesh_plane
...

@GeometryView('Trimesh truncated sphere', duration_guess=1)
def create_truncated_sphere(self, params, **kwargs):
height = params.height

# create sphere mesh

# create intersection plane
plane_normal = (0, 0, -1)
plane_origin = (0, 0, height)

truncated_sphere = slice_mesh_plane(
mesh=sphere_mesh,
plane_normal=plane_normal,
plane_origin=plane_origin,
cap=True,
)
``````

### Exporting the scene

Finally, all we need to do is export this whole scene (fun-fact, multiple Trimesh objects can be included in a single scene) to a `gltf` object.

``````scene = Scene(geometry={"truncated_sphere": truncated_sphere})
# export scene as gltf
geom = File()  # create a writable file
with geom.open_binary() as w:
w.write(gltf.export_glb(scene))
return GeometryResult(geom, geometry_type="gltf")
``````

So if you ever feel held back by the VIKTOR Geometry toolbox, know that there is always a way to hack yourself around it and create the beautiful visuals you need!! ## Full code

For the lazy among us (and let’s face it, a good engineer is a lazy engineer) the full functional app-code for this example can be found here:

Complete code

``````from trimesh import Scene
from trimesh.creation import icosphere
from trimesh.exchange import gltf
from trimesh.intersections import slice_mesh_plane

from viktor.core import ViktorController, File
from viktor.views import GeometryResult, GeometryView
from viktor.parametrization import NumberField, Parametrization, Lookup

class CalculationParametrization(Parametrization):
height = NumberField('Height (h)', suffix='mm', default=0)

class CalculationController(ViktorController):
label = 'Trimesh scene creator'
parametrization = CalculationParametrization

@GeometryView('Trimesh truncated sphere', duration_guess=1)
def create_truncated_sphere(self, params, **kwargs):
height = params.height

# create sphere mesh

# create intersection plane
plane_normal = (0, 0, -1)
plane_origin = (0, 0, height)

truncated_sphere = slice_mesh_plane(
mesh=sphere_mesh,
plane_normal=plane_normal,
plane_origin=plane_origin,
cap=True,
)

scene = Scene(geometry={"truncated_sphere": truncated_sphere})
# export scene as gltf
geom = File()  # create a writable file
with geom.open_binary() as w:
w.write(gltf.export_glb(scene))

return GeometryResult(geom, geometry_type="gltf")

``````

3 Likes