I have never come across any (free) 3D meshing software that is really quick and easy to use that creates reliable tetrahedral meshes. If you have, then please let me know in the comments!
The nearest thing I have found is DistMesh http://persson.berkeley.edu/distmesh/ which I have been playing with recently. This is a small bunch of MatLab functions that seem to wrap MatLab’s own commands (which in turn wrap Qhull I think), with the aim of easing the process of making simple meshes for finite element simulations.
- It allows you to define surfaces via the distance from any point in space to the surface. i.e. an equation which is zero on the surface, negative ‘inside’, and positive ‘outside’. In practice these are very similar to the mathematical equation of that surface that you will recognise from maths.
- You can then do nice set operations to combine the distance equations to make complex shapes (example below).
- It then tries to ‘jiggle around’ nodes to make ‘more equilateral’ triangles/tetrahedrons, for better finite element meshes. It does this by pretending element edges are springs, much in the same way as some of the cell-based Chaste simulations work.
- It can make surface or volumetric meshes, with much the same interface.
Cons (with the caveat that I only spent a day and a half playing with this):
- The jiggling of the mesh is very slow for medium-to-large 3D meshes.
- Getting the correct ‘distance’ equations can be a little bit mind bending.
- Its stability is very sensitive to the ‘bounding box’ and initial mesh spacing you choose.
- Gaps can develop in surfaces.
Here’s a little example that shows how nice the set operations are:
% Main matlab call to DistMesh
% * The first argument is your surface definition (see below).
% * The second argument is a refinement function, you can refine
% more or less depending on where you are as per surface
% definition. The @huniform tells it you want uniform mesh
% edge lengths everywhere. % * 0.1 is the default 'h' edge length % * [-1,-1,-1;1,1,1] is the bounding box for this mesh % * The last argument can define any fixed nodes that % you want to have. [p,t]=distmeshnd(@my_shape,@huniform,0.1,[-1,-1,-1;1,1,1],); %% And this is the function that defines your shape function d=my_shape(p) x=p(:,1); y=p(:,2); % And cylindrical polar co-ordinates z=p(:,3); r=sqrt(x.^2+y.^2); d1=r-1; % Negative within r=1, positive outside d2=z-1; % Negative below z=1, positive above d3=-z-1; % Negative above z=-1, positive below % Then simply the intersection of these gives % you the interior of a cylinder. d=dintersect(dintersect(d1,d2),d3); % And you can take away areas in the same way, % here we take the difference of a set that is made % up of negative distances within a sphere of radius r=0.5. d=ddiff(d, sqrt(x.^2+y.^2+z.^2)-0.5); end
This gives you the following fairly complex shape in a very simple way:
…and you can see it has been fairly nicely meshed after a few iterations of the spring thing.
Now I wanted to do something similar, with a cuboid with a couple of nice dents in the side. Unfortunately this was a bit slow and the spring-adjustments seemed unstable. There are some hard-coded tolerances to play with in ‘distmeshnd’, but I couldn’t find a winning combination. So instead, I went for a 2D surface generation using DistMesh ‘distmeshsurface’ command, with the volumetric mesh being computed afterwards by Tetgen (new version out as of Nov 2013). Again, not all went to plan, if I leave the DistMesh surface mesher iterating away it gives this:
…with funny holes along 3 sides. But when I inserted a ‘break’ command in the main iteration loop it gave its sensible initial guess of:
…which is a very good start. You might notice that it has lined up all the diagonals of the triangles (probably because I broke it out of the iteration loop). This is usually sub-optimal for cardiac electrophysiology, you really want them in alternating directions so as not to introduce any bias in the conduction direction (interesting study for someone?). So I threw a few “refine a bit” options at TetGen and it did the 3D mesh and refined the surface too, which gets rid of the regular structure nicely:
I have ended up with a mesh I am happy with, after only a day and a half of struggle! Hope this could be useful to someone, but it still seems as if there should be an easier way? Please let me know if you find one…