transforming non-uniform sized 3D mask to mesh or tet

76 views
Skip to first unread message

Changran Geng

unread,
Mar 16, 2023, 7:20:30 AM3/16/23
to iso2mesh-users
Hi all, 

I have a mask from the CT image, and trying to transform it to mesh. I have a following question.
As we know the dimension of the voxel of the CT image is usually not uniform, for example to say the dimension of each voxel can be 1mm *1 mm* 3 mm.
When I use the s2m or v2m, how could I tell the functions the above information?

Thank you very much for help.

Best,
Changran

Qianqian Fang

unread,
Mar 16, 2023, 9:48:42 AM3/16/23
to iso2mes...@googlegroups.com, Changran Geng
if the domain is simple, you can still call v2s() to extract the surface, and scale the x/y/z columns in the node output by the respective voxel size. This essentially stretches the surface mesh and creates a mesh of anisotropic density, however, when you call s2m() to produce tetrahedral meshes, as long as opt.radbound and opt.distbound is sufficiently small, the anisotropic triangles will largely remeshed without losing accuracy. below you can see an example of surface scaling and then s2m output.

alternatively, you can remesh the surface (remeshsurf) before passing it s2m.

if your domain is complex, you can still directly call v2m(.., 'cgalmesh') to create a tetrahedral mesh. then scale the node coordinates by voxel sizes, this creates an anisotropic tetrahedral mesh. You can then pass this stretched mesh to meshrefine() and play with the opt parameter. As long as opt imposes a more stringent quality or size constraint, the anisotropic elements will be refined and make the mesh more uniform.


the x/y/z scaling factors can be directly passed to v2s/vol2surf via the diagonal elements of the opt.A field, see



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/f9b69390-75b5-43d6-82a9-03c6f898bd23n%40googlegroups.com.


Changran Geng

unread,
Mar 16, 2023, 11:27:13 AM3/16/23
to Qianqian Fang, iso2mes...@googlegroups.com
Dear Dr Fang,

Thank you very much for your kind reply. Yes, I also found some thread discussing this topic in the forum. It can be well solved.
But I have another issue when using v2s and s2m, I attached the test code and mask that I would like to use. It actually have the skin and the brain, similar to the example you gave. It gives some error messages about the mesh intersection etc. But I couldnot found those errors.
Do you have any suggestions on this kind of error? Is there any efficient tools you recommend in iso2mesh to solve this problem? 

Thank you very much!
Best regards,
Changran


TestIso2Mesh.zip

Qianqian Fang

unread,
Mar 18, 2023, 12:00:44 PM3/18/23
to iso2mes...@googlegroups.com, Changran Geng

hi Changran,

I ran your script, your v2s output contains very large number nodes (80k for each layer, 160k nodes total). Because 80k node is the default maximum node number for v2s, that means both surfaces had encountered issues and could not finish surface extraction.

This is a combination of two things: 1) your opt.distbound setting is too small, and 2) a known issue with CGAL where it gets trapped at "non-manifold" nodes and hits an infinite loop for refinement, see

https://github.com/fangq/iso2mesh/issues/5


I found that if you relax your distbound setting, v2s can complete with a much less node number. If I comment out your line opt(i).distbound=..., v2s out a surface with only 9136 nodes with good/comparable accuracy.

Aside from removing the distbound setting, another change I made is to insert a surface smoothing step before s2m, you can call

no=sms(no,fc(:,1:3),20);

to apply 20 iterations of smoothing, this makes both surfaces quite nice.

in order to correctly label the two regions, I also added

seeds=surfseeds(no,fc);
[node,elem]=s2m(no,fc,1,100, 'tetgen', seeds);

to extract a seed point for each closed compartment, this can be passed to s2m to correctly label each region

my updated script can be found below, along with the output mesh screenshots. by the way, I felt your data aspect ratio is not correct.

Qianqian


 
load('cleanimgfull.mat');
clear opt;

% set method for vol2mesh to 'simplify' to use these option
for i=1:2
  opt(i).side='lower'; %
  opt(i).radbound=4; % set surface triangle maximum size
  %opt(i).distbound=0.2; % set max distance that deviates from the level-set
  opt(i).A=diag([0.9,0.7,3]);
  opt(i).B=[0 0 0];
end

[no,fc]=v2s(cleanimgfull,[1,2]-0.5, opt);

no=sms(no,fc(:,1:3),20);
seeds=surfseeds(no,fc);

figure
plotmesh(no(:,[2 1 3]),fc,'facealpha',0.7);

[node,elem]=s2m(no,fc,1, 100, 'tetgen', seeds);
%[node,elem]=s2m(no,fc,1, 100, 'tetgen1.5');  % you can also auto-label with 'tetgen1.5', but you don't know which is which

 
figure
plotmesh(node,elem, 'y>160')



On 3/16/23 11:26, Changran Geng wrote:
Dear Dr Fang,

Thank you very much for your kind reply. Yes, I also found some thread discussing this topic in the forum. It can be well solved.
But I have another issue when using v2s and s2m, I attached the test code and mask that I would like to use. It actually have the skin and the brain, similar to the example you gave. It gives some error messages about the mesh intersection etc. But I couldnot found those errors.
Do you have any suggestions on this kind of error? Is there any efficient tools you recommend in iso2mesh to solve this problem? 

Thank you very much!
Best regards,
Changran



On Thu, Mar 16, 2023 at 9:48 PM Qianqian Fang <q.f...@neu.edu> wrote:
if the domain is simple, you can still call v2s() to extract the surface, and scale the x/y/z columns in the node output by the respective voxel size. This essentially stretches the surface mesh and creates a mesh of anisotropic density, however, when you call s2m() to produce tetrahedral meshes, as long as opt.radbound and opt.distbound is sufficiently small, the anisotropic triangles will largely remeshed without losing accuracy. below you can see an example of surface scaling and then s2m output.

alternatively, you can remesh the surface (remeshsurf) before passing it s2m.

if your domain is complex, you can still directly call v2m(.., 'cgalmesh') to create a tetrahedral mesh. then scale the node coordinates by voxel sizes, this creates an anisotropic tetrahedral mesh. You can then pass this stretched mesh to meshrefine() and play with the opt parameter. As long as opt imposes a more stringent quality or size constraint, the anisotropic elements will be refined and make the mesh more uniform.


the x/y/z scaling factors can be directly passed to v2s/vol2surf via the diagonal elements of the opt.A field, see



Qianqian



On 3/16/23 02:15, Changran Geng wrote:
Hi all, 

I have a mask from the CT image, and trying to transform it to mesh. I have a following question.
As we know the dimension of the voxel of the CT image is usually not uniform, for example to say the dimension of each voxel can be 1mm *1 mm* 3 mm.
When I use the s2m or v2m, how could I tell the functions the above information?

Thank you very much for help.

Best,
Changran
--
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/f9b69390-75b5-43d6-82a9-03c6f898bd23n%40googlegroups.com.


--
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.

Changran Geng

unread,
Mar 28, 2023, 2:22:37 PM3/28/23
to Qianqian Fang, iso2mes...@googlegroups.com
Dear Prof. Fang,

Thank you very much for your kind reply and great suggestions!
Following your suggestions, I relaxed the distbound and got fewer node number, however the error of self-intersection still happens for some cases.

With many attempts, I did not get a good workaround, could you help me looking into this?

I attached the example data and code in the google drive as follows,

Hope you can take some time to help.

Thank you!
Best regards!
Changran


<head_mesh.png>

Qianqian Fang

unread,
Mar 28, 2023, 5:51:53 PM3/28/23
to Changran Geng, iso2mes...@googlegroups.com
Changran,

v2s->s2m only works if your multiple isosurfaces are not intersecting to each other. when they do intersect, it is quite a complex task to mesh them, we even went for the full length of this by publishing a paper just for this purpose!

please check out our Brain2mesh paper at


especially, the surface mesh processing workflow specifically for the purpose of meshing multi-shell surfaces that are intersecting can be found in Fig. 3.

it depends how you want to handle the "touching" part of intersecting shells - meaning that if it is acceptable to separate them by pushing in-surface inward, or out-surface outward, or both. in any case, you should call surfboolean and check out these options


or call meshfix


again, surface repairing is an extremely difficult case in mesh generation and shall not be underestimated.

Qianqian
Reply all
Reply to author
Forward
0 new messages