Toolboxes is a sub-package where useful Python modules contributed by users are stored.

STLtoVoxel

Information

Author/Contact: Kartik Bansal (kartikbn21000@gmail.com)

This package provides the ability to directly model real objects without having to build their geometries manually using geometry primitives such as the #edge, #plate, #box etc.. commands. It specifically provides a tool to convert a STL file, which can be produced by many CAD software packages, to a voxelised mesh (FDTD Yee cells) which is saved as a geometry file in HDF5 format suitable for directly importing into gprMax.

This package was created as part of the Google Summer of Code programme 2021 which gprMax participated. The package uses the stl-to-voxel Python library by Christian Pederkoff.

License: Creative Commons Attribution-ShareAlike 4.0 International License

Attribution/cite: TBC

Package contents

  • stltovoxel.py is the main script which should be executed to convert a STL file to a voxelised mesh which is saved as a geometry file in HDF5 format suitable for directly importing into gprMax.

  • examples is a folder containing example STL files as well as gprMax input files that can be used to import the resulting HDF5 geometry files.

  • convert.py, perimeter.py, slice.py are modules adapted from the stl-to-voxel Python library by Christian Pederkoff.

  • license.md is the license for the stl-to-voxel Python library by Christian Pederkoff.

Installation

STLtoVoxel and its numpy-stl dependency are installed automatically with gprMax. No separate toolbox installation is required when gprMax is installed from PyPI or from source.

How to use the package

The main script is stltovoxel.py which should be run at the command line and takes two arguments:

  • path is base path to the folder containing the STL file(s) to convert.

  • -dxdydz is the spatial discretisation of the generated voxelised mesh. It should be given as a floating point number.

STL has no standard coordinate unit. The historical toolbox assumed millimetres and this remains the default. Use --unit m, --unit mm, or --unit um explicitly for new workflows.

For a directory containing several parts, create an editable assignment table before conversion:

python -m gprMax.toolboxes.STLtoVoxel.stltovoxel anatomy \
    --prepare anatomy.csv

Then convert with:

python -m gprMax.toolboxes.STLtoVoxel.stltovoxel anatomy \
    -dxdydz 0.002 --assignments anatomy.csv

The CSV maps file independently to material_name and geometry_tag. For example, left and right eyes may share a vitreous material while retaining separate tags. Higher-priority files overwrite lower-priority files wherever closed surfaces overlap. Filename stems become tags when no assignment file is provided.

Material names must not contain +: gprMax reserves it for automatically averaged material IDs. Use _ instead. Without an assignment CSV, the STL filename stem is also the material name; if it contains +, use --prepare and edit material_name, then convert with --assignments. The source filename itself need not change. The same restriction applies to name and metadata.original_id when the converter reuses an edited companion JSON database. This does not restrict averaged materials restored from files produced by gprMax’s GeometryObjectsWrite.

The physical dimensions of the voxelised object will depend on the size of the object in the original STL file and the spatial discretisation chosen.

Method of rotating STL file

Author/Contact: Owen Wilkinson (owenwilkinson39@gmail.com)

The STLtoVoxel command enables real-world objects saved in stl format to be converted and imported directly into gprMax. However, this command currently does not support directional manipulation of geometries once inside gprMax. Bambu Studio, is a free, open-source application commonly used for slicing 3D printing models that provides a simple solution to this limitation. Importantly, Bambu Studio uses the same axis orientation as gprMax, making it well-suited for preparing stl, 3mf, oltp, stp, step,svg, amf or obj files before importing. The software is lightweight, intuitive, and requires no account creation. Skipping all setup steps will open a basic workspace with a printing base plate visible. Using the previous example of the Stanford Bunny, opening its STL file in Bambu Studio will display the model positioned on the base plate, as shown below.

_images/Rotated_Bunny_Import.png

Fig. 77 Image of the Stanford bunny STL file imported into Bambu Studios

The information panel in the bottom-right corner displays the STL object’s dimensions in the same format used in gprMax. To rotate the object about any axis, use the rotate icon located in the top toolbar. As the STL object is rotated, the dimensions shown in the bottom-right panel will update accordingly.

_images/Rotated_Bunny_Upside_down.png

Fig. 78 Image of the Stanford bunny STL file rotated upside down

Finally, once the object is correctly oriented in the x, y, and z planes for the gprMax model, use the menu path File → Export → Export all objects as one STL. This will generate a new STL file containing the updated orientation. As before, convert this new STL file into an HDF5 file for use within gprMax, following the procedure outlined in the previous section.

_images/Rotated_Bunny_Export.png

Fig. 79 Image of the Stanford bunny STL file exported with new orientation

_images/Rotated_Bunny_ParaView.png

Fig. 80 Image of the Stanford bunny rotated inside Paraview

Example

To create a voxelised mesh (HDF5 geometry file) from the ubiquitous Stanford bunny STL file, using a spatial discretisation of 1mm:

python -m gprMax.toolboxes.STLtoVoxel.stltovoxel gprMax/toolboxes/STLtoVoxel/examples/stl/Stanford_Bunny.stl -dxdydz 0.001

Since the number of voxels are 108 x 88 x 108 and the spatial discretisation chosen is 1mm, the physical dimensions of the Stanford bunny when imported into gprMax will be 0.108 x 0.088 x 0.108m.

The converter also creates an editable _materials.json database beside the generated HDF5 file. Its constitutive values are initially null because the STL file contains no electromagnetic properties. They must be filled in before running gprMax. The stable keys in the database are also stored in /material_keys in the HDF5 file, so their order cannot become detached from the voxel indices. Rerunning the conversion preserves an existing database when its material keys still match, so user-entered properties are not overwritten.

The HDF5 file also contains tag_data and tag_names. Tag IDs describe the final voxelised cells after overlap resolution and are imported by GeometryObjectsRead. They are not material IDs and dielectric smoothing does not alter their membership.

 1{
 2  "schema": "gprMax-material-database",
 3  "schema_version": 1,
 4  "database": {
 5    "id": "Stanford_Bunny_geo_materials",
 6    "name": "Stanford bunny example materials",
 7    "version": "1.0.0",
 8    "description": "Example assignment for the STLtoVoxel Stanford bunny."
 9  },
10  "materials": {
11    "material_000_Stanford_Bunny": {
12      "name": "Sand",
13      "model": "constant",
14      "base": {
15        "relative_permittivity": 3.0,
16        "electric_conductivity_s_per_m": 0.0,
17        "relative_permeability": 1.0,
18        "magnetic_conductivity_s_per_m": 0.0
19      },
20      "metadata": {
21        "original_id": "sand",
22        "quality": "illustrative example, not a universal sand property"
23      }
24    }
25  }
26}

The following Python script imports the generated geometry and selects its database by name. The example database assigns sand to the bunny.

 1from pathlib import Path
 2
 3import gprMax
 4
 5# File path for output
 6fn = Path(__file__)
 7
 8# Discretisation
 9dl = 0.001
10
11# Domain
12x = 0.148
13y = 0.128
14z = 0.148
15
16scene = gprMax.Scene()
17
18title = gprMax.Title(name=fn.with_suffix("").name)
19domain = gprMax.Domain(p1=(x, y, z))
20dxdydz = gprMax.Discretisation(p1=(dl, dl, dl))
21time_window = gprMax.TimeWindow(time=10e-9)
22
23scene.add(title)
24scene.add(domain)
25scene.add(dxdydz)
26scene.add(time_window)
27
28go = gprMax.GeometryObjectsRead(
29    p1=(0.020, 0.020, 0.020),
30    geofile="stl/Stanford_Bunny_geo.h5",
31    material_database="Stanford_Bunny_geo_materials",
32)
33
34gv = gprMax.GeometryView(
35    p1=(0, 0, 0),
36    p2=domain.props.p1,
37    dl=(dl, dl, dl),
38    filename=fn.with_suffix("").name,
39    output_type="n",
40)
41
42scene.add(go)
43scene.add(gv)
44
45gprMax.run(scenes=[scene], geometry_only=True, outputfile=fn)
_images/stanford_bunny_stl.png

Fig. 81 Image of the Stanford bunny STL file

_images/stanford_bunny.png

Fig. 82 FDTD geometry mesh showing the Stanford bunny