# Metafor

ULiege - Aerospace & Mechanical Engineering

### Sidebar

doc:user:geometry:mesh:geniso

﻿

# Biomech GenIso Mesher

This mesher is used to generate a 3D surface mesh from a 3D segmented image.

## Mono-material mesh

The input is a 3D segmented binary image. It contains two values: voxels with a $0$ value are located outside of the object to mesh, voxels with a non-zero value are located inside.

The image must be .vtk, or event better .vti, which is more compact. If it is not the right format use Slicer3D, Paraview or my interface geniso/tools/gui4.py to change it.

First, the geniso tools must be loaded:

 import geniso.tools.generalTools as generalTools
import geniso.tools.meshingTools as meshingTools
import geniso.tools.imagingTools as imagingTools

Then the image must be loaded:

 image = generalTools.loadVtkImageXML(imageFileName)

Afterwards, the following set of commands is used to generate a surface mesh of the boundary of the segmented image:

 gen = GenerateMesh(generalTools.vtkImageDataToCpp(image))
gen.execute()
smooth = SmoothMesh(gen.getSurf())
smooth.smoothWithFctFromPoly(nbr,spx,spy,spz,nmin,interpol,type)

where the parameters are described in the table below.

In practice, GenerateMesh(image).execute() creates a triangulation of the boundary of the segmented object in the binary image given. Because of the spatial discretization of the image, the mesh which is generated is not smooth, since the steps of the image are kept. The class SmoothMesh() is used to eliminate these irregularities while keeping the geometry described in the image. It does so with the construction of an implicit function, described by the parameters nmin, interpol and type (for more details: http://hdl.handle.net/2268/136159).

Then, the vtkPolydata is retrieved with the command:

 poly = generalTools.genisoMeshToPolyData(smooth.getSurf())

TetGen is used to get a tetrahedral volume mesh of the object from the triangular surface mesh of the boundary of the object:

 ugrid = meshingTools.callTetgen(poly)

A vtkUnstructuredGrid is retrieved. To save it on disk: generalTools.saveUgridXML('ugrid.vtu',ugrid). Paraview is used to view it. The class LoadMesh, implemented in the file, is used to include it in a Metafor test case:

 groupset.add(Group(1))
mesh = LoadMesh(domain, ugrid, groupset(1) )
mesh.execute()

## Multi-material mesh

This option is used to generate a mesh which contains several material areas: two different bones, a brain with ventricles separated from a tumor, a jawbone with a series of teeth…

In the multi-material case, the segment image representing the geometry must contain several labels: 0 for the background (outside of the object), and a series of non-zero positive values (typically 1, 2, 3…) for each material.

To use the GenIso mesher, the implicit function Fct must first be defined. This function is a continuous equivalency of the discrete segment image, and will allow the mesher to supply a smooth interface between the mesh separating each region.

To define this function, couples of labels of the image are defined, labels between which the mesher must create a triangulation. In addition, these couples are sorted to define the heterogeneous object as a set of closed surfaces on which open surfaces can be attached. In the image below, a tumor (open surface defined by the couple (4, 3)), is tied on the external boundary of the brain (closed surface defined by the union of the couples (3, 0) and (4, 0)).

Consequent, the syntax is as follow:

  fct = Fct()
surf1 = fct.defineClosedSurface()
surf1.mesh(3,0)
surf1.mesh(4,0)
surf2 = fct.defineOpenSurface()
surf2.mesh(4,3)
fct.setEpsilon(eps)
fct.setNmin(nmin)
fct.setType(type)
fct.setInterpol(interpol)
fct.setVtkImageFromPython(generalTools.vtkImageDataToCpp(image))
fct.build()

Afterwards, the mesh can be generated with the commands:

  gen = GenerateMesh(fct)
gen.getRegularGrid().setResolution(res)
gen.execute()
poly = generalTools.genisoMeshToPolyData(gen.getSurf()) // vtkPolyData

From this surface multi-regions mesh, TetGen is used to generate the volume mesh in each of these regions. To do so, TetGen must be given a point, seed situated in each of the regions to be meshed (this point can be found, for example, by loading the vtkPolydata in the graphical interface geniso/tools/gui4.py using the option point).

  seedbrain= [118.3,160.5,75]
seedtumor = [118,196.9,71]
regionSeeds = [seedbrain,seedtumor]
regionVolmax = [volmax, volmax]
ugrid = meshingTools.callTetgenMultipleRegions(poly, regionSeeds, regionVolmax)

Then, the mesh is loaded in Metafor:

  labels = [1,2]  // the two labels of the regions located in the ugrid (see visu in Paraview)
grp = [groupset(1),groupset(2)]

mesh.setFillMeshPoints(True)
mesh.setGrpLabels(labels)
mesh.execute()

## Parameters

Parameter Meaning and recommended value
nbr number of iterations of the smoothing function
recommended: 4
spx,spy,spz Spacing of the grid used to generate the mesh
recommended = gen.getRegularGrid().getDx(),.getDy(),.getDz()
res Resolution of the grid used to generate the mesh
recommended: image.GetDimensions()[0] if the grid defined by the initial image is to be kept
eps relative distance allowed between the initial image and the function Fct
recommended: 1./image.GetDimensions()[0], which corresponds to a distance of a voxel width
nmin smoothing degree
recommended: between 15 and 100
interpol 0: approximation function, 1: interpolation function
recommended: 0 for a smoother surface, 1 for a geometry closer to the initial image
type 1: linear, 2: quadratic
recommended: 1 for robustness, 2 for a smoother surface