Defining complex geometries using trimesh
Defining complex geometries using trimesh#
Tidy3D offers four primitive geometric shapes: Box, Cylinder, Sphere, and PolySlab. An extensive array of intricate geometrical configurations can be defined from these fundamental building blocks by manipulating their properties and hierarchical arrangements. For instance, our tutorials on the Luneburg lens waveguide size
converter and the Fresnel lens showcase the creation of curved surfaces through the strategic layering of cylindrical elements.
Beyond the in-built primitives,
Tidy3D accommodates external geometrical specifications in either the gds or stl file formats, allowing users to import custom geometries created in their preferred design tools. Additionally, compatibility with external libraries like gdstk and
shapely opens the gateway to even more complex geometric possibilities. Using gdstk to create various waveguide structures has been demonstrated in various examples such as the polarization splitter and rotator based on 90 degree bends.
In this tutorial, we’ll introduce an alternative avenue for crafting complex geometries using the trimesh library. Through examples featuring a torus and an ellipsoid, we’ll guide you through the process of defining a mesh structure that is directly usable in
Remember to install
pip install "tidy3d[trimesh]", which will install optional dependencies needed for processing surface meshes.
import tidy3d as td import trimesh import numpy as np import matplotlib.pyplot as plt
After the mesh is created, we can visualize the mesh in 3D.
n_sections = 100 # how many sections to discretize the mesh # create a ring mesh ring_mesh = trimesh.creation.annulus(r_min=9, r_max=10, height=1, sections=n_sections) # plot the mesh ring_mesh.show()
To use this geometry in a Tidy3D simulation, we need to convert the mesh into a Tidy3D TriangleMesh geometry. The
from_trimesh() method conviently converts a mesh to a Tidy3D geometry. From there, you can further define Tidy3D Structure and put it into a Simulation.
# define a tidy3d geometry from a mesh ring_geo = td.TriangleMesh.from_trimesh(ring_mesh) # plot a 2d cross section of the geometry ring_geo.plot(z=0) plt.show()
In addition, you can easily apply operations to a mesh such as translation and rotation. Here we demonstrate how to translate the previously created ring by a vector
(5, 10, 0). The resulting ring is centered at
(5, 10, 0).
# translate the ring ring_mesh.apply_translation([5,10,0]) # define a tidy3d geometry from a mesh ring_geo = td.TriangleMesh.from_trimesh(ring_mesh) ring_geo.plot(z=0) plt.show()
In a grating coupler simulation, very often we want to use a tilted cylinder to model the fiber core at an angle. This can be done with the help of trimesh too. First create a cylinder and then apply a rotation transformation to it.
# create a cylinder cylinder_mesh = trimesh.creation.cylinder(radius=2, height=10, sections=n_sections) # apply rotation rot_x = trimesh.transformations.rotation_matrix(np.radians(45), [1,0,0]) cylinder_mesh.apply_transform(rot_x) cylinder_mesh.show()