Contents
Target Outcome
Complete outline of model development process for mutli-layer tissue models for input into Febio.
Input
- Indentation and force data from in vitro experiments.
- Completed leg or arm assembly, with each individual tissue layered modeled separately.
Procedures
Creation of Model Assembly
Creating Surface Representations
This process is overall similar to development of lumped tissue models, but has more steps given the relative increase in model complexity.
Starting with Image Segmentation of separate tissues, generate 4 different stl files. There are 3 files to be included in the model: the bone by itself, the bone merged with the muscle, and finally the bone merged with the muscle and fat. The fourth file is the bone merged with the muscle, fat, and skin layer, and is used to determine if constant skin thickness is a reasonable assumption, and then the distance to be extruded. The model consisting of the bone_muscle_fat and the bone_muscle_fat_skin should be cut ~5 slices on both ends relative to the muscle_fat layer. This procedure can be done by joining the individual layers into a single block, which can be done in Slicer by using the Editor. Within the Editor, the Change Label Effect makes one color of label change to another. This way different tissue layers can be joined together to create multiple "lumped" portions of the leg. Joining the bone to the lumped portions is also recommended. Use the Model Maker to generate the surface, and save all 3 (or 4) parts as separate stl files.
Remeshing the Surface
Using MeshLab, individually open the stls that were generated. The goal is to remesh the surface with triangles that are approximately similar in size at the desired mesh density. This process should be done for each of the stls.
First use Poisson Reconstruction. This does not produce the even triangle size that is desired, but the resulting surface can then be isoparameterized itself. Sometimes this reconstruction may produce undesirable results. Switching the octree depth and solver divide to 7 tends to give better results over the default settings without a dramatic increase in runtime. Detailed instructions on Poisson Reconstruction can be found here.
MeshLab's Iso Parameterization does an excellent job of remeshing, but it is very fickle and may crash MeshLab. It is recommended to save before attempting. Increasing the convergence precision (to 3 or 5) and toggling the double step parameter can sometimes fix crashing. Different poisson reconstruction settings might also fix crashes. Detailed instructions on Iso Parameterizing can be found here.
The next step is to remesh the iso parameterized model. A sample rate of 5 was primarily used for quad models as per our mesh convergence study. The bone model is meshed at a sample rate (typically 8).
When isoparmeterization has been completed, it is often useful to use Taubin Smoothing before saving the reconstructed mesh. Default parameters are usually employed for this. Ensure the mesh is manifold.
Creating the Skin Layer
The skin layer was not generated originally because its small thickness would often result in the fat layer cutting through it. As such, the skin is generated by extruding the fat stl with a series of python scripts. Starting with your meshed bone_muscle_fat stl file, first run the python script Plane_Cut_Mesh.py found here. This script removes the ends of the fat stl file. The cutting works best when the PlaneCut function is commented out, although this makes the skin volume not as smooth along the edges. The normals need to be flipped on the surface as well. The file is then extruded a negative distance with ExtrudeMesh.py found here. A constant extrusion length can be considered a reasonable assumption after viewing the distribution of skin thickness for each model with the script SkinThickness.py found here. Note that in order to run this you will have to run Plane_Cut_Mesh.py on your bone_muscle_fat raw stl and on the bone_muscle_fat_skin raw stl.
Cutting the Mesh
When the surfaces were created, every internal layer was included for each part. This was to allow the internal layer to be cut from the subsequent external layer, ensuring a perfect fit at each interface. If this was not done the remeshing and smoothing steps will have created a small, but noticeable amount of overlap. Cutting the bone_muscle file with the bone stl file and cutting the bone_muscle_fat file with the bone_muscle file will prevent this issue.
This step can be accomplished with either of 2 scripts. The best option is to use the Python script bpy_CutStlWithStl.py found here. Tweaking the decimation rate may be necessary depending on mesh density (or turned off, although it typically helps remove poor aspect ratio triangles). If blender or python3 are not readily available, this can also be accomplished by using the Python script CutStlWithStl.py found here. The blender script is preferable because it is better at mesh generation at the cut site, as the vtk script will sometimes generate intersecting triangles that need to be manually fixed. Use Meshlabs Filter>Selection>Select Self Intersecting Faces to visualize and fix them. Note that this filter frequently reports false positives, so only spend time fixing triangles that actually are problematic. After this step, you should have meshed surface representations of the bone, muscle and fat layers that fit perfectly with each other, as well as a skin mesh of wedge elements.
Placement of the ultrasound probe
The probe Stls can be found at https://simtk.org/svn/multis/app/Registration/Probe%20STLS/
Once you have a local copy you can use the script initial_probe_positions.py found here.
In addition to the stl you will need the registration xml for the model you are using, it will be named something like CMULTIS008-1_UL_US_CT.xml for the upperleg of specimen 008.
The probe often overlaps too much with the model, so it can be manually moved in meshlab, or with the Python script Probe_Overlap_Transform.py found here if you are trying to replicate the experimental data.
Model Assembly
Once all surface meshes have been created and the probe is properly positioned, it is time to make the Connectivity xml document that the model assembly script will use to prepare the model. Here is a sample xml file. Multiplier values may need to be changed based on your model. The skin ties especially should be examined, as the skin is composed of both tri6 and quad8 elements. Febio does not support having different element types in one surface definition, so make sure the contact surface only includes tri6 elements. This also means the current All_Skin_Faces definition in the geometry file is invalid. Converting the bone to a quad mesh (easily done in salome) will reduce penetration of the muscle into the bone.
<Assembly> <Bone> <file>bone.stl</file> <material>rigid</material> <Tie> <Muscle type="proximity" multiplier=".2"/> </Tie> </Bone> <Muscle> <file>bone_muscle_Blender_Cut.stl</file> <quad/> <material>elastic</material> <Tie> <Fat type="proximity" multiplier=".2"/> <Bone type="proximity" multiplier=".2"/> </Tie> </Muscle> <Fat> <file>/bone_muscle_fat_Blender_Cut.stl</file> <quad/> <material>elastic</material> <Tie> <Muscle type="proximity" multiplier=".2"/> <Skin type="proximity" multiplier=".2"/> </Tie> </Fat> <Skin> <file>/skin.med</file> <quad/> <material>elastic</material> <Contact> <Probe type="normals" multiplier="20"/> </Contact> <Tie> <Fat type="proximity" multiplier=".2"/> </Tie> </Skin> <Probe> <file>/oriented_probe.stl</file> <material>rigid</material> <Contact> <Skin type="normals" multiplier="20"/> </Contact> </Probe> </Assembly>
Converting To Febio
Running StlToMed.py, followed by MedToFebio.py, both of which are found here, using your connectivity xml will result in generation of a febio input file and an accompanied geometry file. The input file is where simulation parameters can be edited, while the geometry file contains element and surface definitions as a separate file given the length of this file. Note the models generated will be rather large in size (the largest we experienced with no model simplification needed 90 GB RAM), so high performance computing may be a necessity to run these files.
Limitations of Layered Modeling Strategy 1
This strategy has proven unsuccessful when working with regions that have identical or nearly identical layer boundaries (e.g. the lower leg regions). Adaptive Meshing is more suitable for these regions.
Output
- Febio input file
- Febio geometry file