To build a labeled volume mesh for a forearm model with muscles and bones

154 views
Skip to first unread message

Shihan Ma

unread,
Oct 12, 2021, 4:41:11 PM10/12/21
to iso2mesh-users

Hi, Dr. Fang,

Thank you for developing Iso2Mesh. I encountered some problems when trying to generate meshes for a forearm model by using Iso2Mesh. Could you please give me some advice on the following conditions?

Our 3D forearm model was established by SolidWorks, including several muscle volumes, two bones, tissues between muscle and skin, and a skin layer. The 3D volumes can be exported to '.stl' files either separately or as a whole. Our purpose is to generate a single labeled mesh volume including all these parts of the forearm model. In other words, the muscles, bones, tissues, and skin should be sequentially labeled 1 to n within the output mesh. I tried the following two approaches and sadly got stuck with both methods.

1. The optimal way is to use ‘vol2mesh’ function to build the mesh from img, so that there is no need to tackle the intersections between muscle surfaces. We have MRI series of the forearm and segmented the muscle contours on some of the axial slices to build the 3D entity in SolidWorks. The primary challenge is that our MRI data is not isotropic. The slice distance along the axial direction is 3 mm while the resolution in the cross-section is around 0.3 mm. Therefore, even though we could segment muscles in each axial slice, the final img will be of the size: 448*448*92, where 92 is the number of axial slices. As a result, the forearm is greatly compressed along the z-axis after being meshed. I haven't found a way to solve this problem. I wondered whether I should first interpolate the slices along the axial direction to get an img with the size around 448*448*920. Could you please recommend some possible software for preprocessing?

2. I tried to use ‘surf2mesh’ function in the following steps. First, I meshed each muscle and bone using ‘surf2mesh’ and labeled them by changing the fifth column of elem. Second, I merged the matrices of elem and nodes by concatenation. Up to this point, the labeled volumes seem to be correct after plotting by plotmesh. Finally, I tried to use 'meshrefine' function to add the nodes of the skin layer and to generate the mesh between the skin and the muscles. However, MatLab was stuck in the function and couldn't output a correct mesh. The command line showed “Warning: Tet …. is degenerate. Mesh reconstruction.”.
I also tried to generate mesh for all muscles at one time by ‘surf2mesh’, where the muscles are all in one stl file. However, it showed that “Tetgen command failed”. I guess it could result from the small intervals between some pairs of muscles.

Could you please give me some advice on the possible solutions?

Thank you for your time!

Best regards,
Shihan

Qianqian Fang

unread,
Oct 21, 2021, 10:37:28 PM10/21/21
to iso2mesh-users
hi Shihan, for some reason I don't see this message in my inbox.

the issue that surf2mesh failed was because your region surfaces intersect each other. You should call surfboolean to resolve intersections first (although it only works well for two regions). Even better, If you can merge triangular meshes of different regions into a single surface (non-self-intersecting) in SolidWorks, and export it to matlab, then s2m/surf2mesh should also work smoothly.

On a related note, this past summer, my MS student, Yuxuan Zhang, wrote a Blender plugin, called BlenderPhotonics


this plugin can serve as a GUI front-end for both iso2mesh and mmc, the detail of this software can be found in his MS thesis


if SolidWorks won't help you merge the surfaces, you can try importing each STL file to blender, and let Blender do the merge, and then BlenderPhotonics can create the mesh (by calling iso2mesh via octave)


because this tool is quite new and we haven't had time to do extensive testing, so I can't be sure if there are other obstacles.


on the other side, with iso2mesh, the more conservative path is to 

1. load stl files to matlab
2. rasterize each ROI using s2v over a shared grid space, ideally with a fine grid
3. merge rasterized ROI masks to form a multi-labeled domain, and
4. call v2m(..,'cgalmesh') to create the tet mesh


Qianqian

Shihan Ma

unread,
Oct 24, 2021, 5:23:13 AM10/24/21
to iso2mesh-users
Hi  Professor Fang,

Thank you for your detailed reply! I'm not sure whether muscles can still be labeled separately in iso2mesh after merged in SolidWorks or by  Blender. Therefore I tried the conservative approach that you recommended. It's promising although with some errors. The errors have not been fixed yet but I think it could be done! Could you please give me some advice? Thank you.
I tried the following steps:

1. Load stl files to matlab by using 'stlread', and get node and face of each muscle by using 'meshcheckrepair';
2. Rasterize the nodes and faces of each muscle by using 'surf2vol' over the same grid space (grid step of 0.25);
3. Merge the 3D img of each muscle by using the command: 
    imgs = imgs + (fillholes3d(img, 0) * muscle_id);
    Here I hope to integrate all regions into one img and label them by their id, from 1 to n. 
    The command ‘cleanimgfull=cleanimg+(cleanbrain>0);’ in 'demo_vol2mesh_ex3.m' could not be used here to merge muscles because the muscles are isolated from each other. However, it will be used to merge the individual muscles with the whole tissues, the same as to merge the brain region with the head region.
4. Call 'vol2mesh' to create the mesh. Sadly, it failed and reported, “Tetgen command failed”. I found that muscles that were located far from each other could be successfully merged while it failed for muscles that were located near each other. I used 'surfboolean' to check that the muscles were truly separated from each other and did not intersect. 
    I wondered whether it is due to the close distance between muscles or the opt settings (I set the 'radbound' as 10, and the step in the shared grid as 0.25). I also tried the 'radbound' as 4 but it still failed.
4-1 Alternatively, I used the 'meshisolatedobj' in FAQ and it worked for merging muscle regions. 
4-2 Furthermore, I wanted to rasterize the 3D mesh of the merged muscles to a volume and merge this volume with the whole tissue. However, the function 'mesh2vol' stuck and didn't result in the expected mask. I intended to generate the final labeled mesh by using vol2mesh after this step.

Could you please give me some advice on the possible solutions? Or could I send the stl files as test data to you by email?

Thank you again for your time!

Best regards,
Shihan

Qianqian Fang

unread,
Oct 24, 2021, 10:15:53 AM10/24/21
to iso2mes...@googlegroups.com, Shihan Ma
On 10/24/21 5:23 AM, Shihan Ma wrote:
Hi  Professor Fang,

Thank you for your detailed reply! I'm not sure whether muscles can still be labeled separately in iso2mesh after merged in SolidWorks or by  Blender. Therefore I tried the conservative approach that you recommended. It's promising although with some errors. The errors have not been fixed yet but I think it could be done! Could you please give me some advice? Thank you.
I tried the following steps:

1. Load stl files to matlab by using 'stlread', and get node and face of each muscle by using 'meshcheckrepair';
2. Rasterize the nodes and faces of each muscle by using 'surf2vol' over the same grid space (grid step of 0.25);


setting a single grid spacing is not enough to ensure that each surface component are rasterized over the same grid space. instead, you should define xi/yi/zi and use them across all surfaces. see demo script for an example

https://github.com/fangq/iso2mesh/blob/master/sample/demo_surf2vol_ex1.m#L22-L25


3. Merge the 3D img of each muscle by using the command: 
    imgs = imgs + (fillholes3d(img, 0) * muscle_id);
    Here I hope to integrate all regions into one img and label them by their id, from 1 to n. 
    The command ‘cleanimgfull=cleanimg+(cleanbrain>0);’ in 'demo_vol2mesh_ex3.m' could not be used here to merge muscles because the muscles are isolated from each other. However, it will be used to merge the individual muscles with the whole tissues, the same as to merge the brain region with the head region.
4. Call 'vol2mesh' to create the mesh. Sadly, it failed and reported, “Tetgen command failed”. I found that muscles that were located far from each other could be successfully merged while it failed for muscles that were located near each other. I used 'surfboolean' to check that the muscles were truly separated from each other and did not intersect.


if you have a multi-labeled volume, you should set the method parameter of v2m/vol2mesh to 'cgalmesh', this is most robust path. see example

https://github.com/fangq/iso2mesh/blob/master/sample/demo_cgalmesher.m#L18


--
You received this message because you are subscribed to a topic in the Google Groups "iso2mesh-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/iso2mesh-users/EUj2ZwZNdMM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to iso2mesh-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/iso2mesh-users/27246698-f290-4ee3-957a-f2fea452593fn%40googlegroups.com.
Message has been deleted

Shihan Ma

unread,
Oct 25, 2021, 9:58:23 AM10/25/21
to iso2mesh-users
Hi  Professor Fang,

Thank you for your advice, so that I finally managed to generate the mesh.

I found that 'cgalmesh' can not be used to generate the meshes of two isolated regions. Therefore, I merged the cross-section of the forearm with the individual muscle regions and then used 'cgalmesh' in 'vol2mesh'.

The generated meshes were dense in some areas and sparse in others, with a mean quality of 0.5879 (std: 0.1748, median: 0.5699) by 'meshquality'. I wondered which attributes of 'opt' in 'meshrefine' would be the best choice to solve this problem. I changed the opt from 10 to 15 in vol2mesh, but it seems that the output mesh remained similar.

Thank you again for your time.

Best regards,
Shihan

Qianqian Fang

unread,
Oct 26, 2021, 12:17:34 PM10/26/21
to iso2mes...@googlegroups.com, Shihan Ma
On 10/25/21 9:58 AM, Shihan Ma wrote:
Hi  Professor Fang,

Thank you for your advice, so that I finally managed to generate the mesh.


glad to hear.


I found that 'cgalmesh' can not be used to generate the meshes of two isolated regions.


upstream CGAL developers had submitted a patch to solve this issue, although I haven't figured out how to compile it properly. eventually, this will be solved once I upgrade all cgal binaries in the next release.

https://github.com/fangq/iso2mesh/issues/7#issuecomment-544141712


a workaround can be found here

http://iso2mesh.sourceforge.net/cgi-bin/index.cgi?Doc/FAQ#How_to_mesh_a_domain_containing_multiple_isolated_objects


Therefore, I merged the cross-section of the forearm with the individual muscle regions and then used 'cgalmesh' in 'vol2mesh'.

The generated meshes were dense in some areas and sparse in others, with a mean quality of 0.5879 (std: 0.1748, median: 0.5699) by 'meshquality'.


there is no particular connection between spatially adaptive element sizes and mean mesh quality - as a matter of fact, mesh refinement is the typical step for achieving higher mesh quality


I wondered which attributes of 'opt' in 'meshrefine' would be the best choice to solve this problem. I changed the opt from 10 to 15 in vol2mesh, but it seems that the output mesh remained similar.


try setting opt.reratio to a lower value and rerun meshquality

https://github.com/fangq/iso2mesh/blob/master/cgalv2m.m#L21


a discussion about this flag can be found in this tetgen page

https://wias-berlin.de/software/tetgen/switches.q.html



Qianqian


You received this message because you are subscribed to the Google Groups "iso2mesh-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to iso2mesh-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/iso2mesh-users/dc95b905-2d63-48ad-9f23-1c820a5febd8n%40googlegroups.com.


Shihan Ma

unread,
Oct 26, 2021, 11:32:37 PM10/26/21
to iso2mesh-users
Hi  Professor Fang,

I set the opt.radbound to 2, the opt.reratio to 1, and maxvol to 4 while using vol2mesh. The mean quality increased to 0.7474. Although the whole mesh was not evenly distributed (some dense while others sparse according to plotmesh), the quality of each element seems to be improved. I'll try to use this mesh for some further analysis.

Thank you again for all your advice. They are really useful.

Best regards,
Shihan

Fang, Qianqian

unread,
Oct 27, 2021, 12:15:01 PM10/27/21
to iso2mes...@googlegroups.com
If you don't like the small volume elements, you can increase opt.distbound to a bigger number. It's default value is 0.5.


From: iso2mes...@googlegroups.com <iso2mes...@googlegroups.com> on behalf of Shihan Ma <mmass...@gmail.com>
Sent: Tuesday, October 26, 2021 11:32:37 PM
To: iso2mesh-users <iso2mes...@googlegroups.com>
Subject: Re: [iso2mesh-users] Re: To build a labeled volume mesh for a forearm model with muscles and bones
 
Reply all
Reply to author
Forward
0 new messages