runTetGen

Below is a demonstration of the features of the runTetGen function

Contents

Syntax

[meshOutput]=runTetGen(inputStruct);

Description

This function creates a temporary .smesh file which it passes to TETGEN (http://wias-berlin.de/software/tetgen/) for tetrahedral meshing. The input structure should contain the following fields:

smeshStruct.stringOpt=stringOpt; Where stringOpt should contain a strin composed of valid TETGEN command line switches (e.g. '-pq1.2VAaY'). See info below and the TETGEN manual.

smeshStruct.Faces=F; Where F is an array for all the model (triangular) faces

smeshStruct.Nodes=V; Where V is the array containing the nodal coordinates

smeshStruct.holePoints=V_holes; Where V_holes describes a point (not part of V) that lies inside a prescribed hole inside the mesh. If V_holes=[] no holes are defined.

smeshStruct.faceBoundaryMarker=faceBoundaryMarker; Where faceBoundaryMarker defines a label for each face denoting its membership to a particular boundary (e.g. all outer faces could have the same boundary label while an internal set of faces defining a hole has a different label).

smeshStruct.regionPoints=V_regions; Where similarly to V_holes the array V_regions defines points (not part of V) that lie inside a specific region (e.g. a material can be contained within another material and this allows you to specify multiple materials with different mesh densities and output labels).

smeshStruct.regionA=regionA; Where regionA is a vector defining the A specification (volume) for the corrensponding regions (as defined in V_regions)

Optional parameters:

smeshStruct.minRegionMarker=2; %Minimum region marker Arbitrary region marker label. Regions are labeled minRegionMarker:1:... for all regions.

smeshStruct.smeshName=smeshName; Where smeshName is the file name for the input .smesh file. Only .smesh files are currently supported as input files. This function generates the .smesh file using the writeBasicSmesh function

Below is a list of command line switches from the user manual:

-p Tetrahedralizes a piecewise linear complex (PLC). -Y Preserves the input surface mesh (does not modify it). -r Reconstructs a previously generated mesh. -q Refines mesh (to improve mesh quality). -R Mesh coarsening (to reduce the mesh elements). -A Assigns attributes to tetrahedra in different regions. -a Applies a maximum tetrahedron volume constraint. -m Applies a mesh sizing function. -i Inserts a list of additional points. -O Specifies the level of mesh optimization. -S Specifies maximum number of added points. -T Sets a tolerance for coplanar test (default 10?8). -X Suppresses use of exact arithmetic. -M No merge of coplanar facets or very close vertices. -w Generates weighted Delaunay (regular) triangulation. -c Retains the convex hull of the PLC. -d Detects self-intersections of facets of the PLC. -z Numbers all output items starting from zero. -f Outputs all faces to .face file. -e Outputs all edges to .edge file. -n Outputs tetrahedra neighbors to .neigh file. -v Outputs Voronoi diagram to files. -g Outputs mesh to .mesh file for viewing by Medit. -k Outputs mesh to .vtk file for viewing by Paraview. -J No jettison of unused vertices from output .node file. -B Suppresses output of boundary information. -N Suppresses output of .node file. -E Suppresses output of .ele file. -F Suppresses output of .face and .edge file. -I Suppresses mesh iteration numbers. -C Checks the consistency of the final mesh. -Q Quiet: No terminal output except errors. -V Verbose: Detailed information, more terminal output. -h Help: A brief instruction for using TetGen.

See the TETGEN manual for more information.

Examples

clear; close all; clc;

Plot settings

fontSize=15;
faceAlpha1=0.3;
faceAlpha2=1;
cMap=gjet(4);
patchColor=cMap(1,:);
markerSize=25;

Example 1: Meshing a model with a single region

Creating geometry

[F,V]=stanford_bunny('g'); %Bunny

C=ones(size(F,1),1); %Face boundary markers (aka face colors)
V_regions=getInnerPoint(F,V); %Define region points
V_holes=[]; %Define hole points
[regionTetVolumes]=tetVolMeanEst(F,V); %Volume estimate for regular tets
stringOpt='-pq1.2AaY'; %Options for tetgen

Mesh using TetGen

%Create tetgen input structure
inputStruct.stringOpt=stringOpt; %Tetgen options
inputStruct.Faces=F; %Boundary faces
inputStruct.Nodes=V; %Nodes of boundary
inputStruct.faceBoundaryMarker=C;
inputStruct.regionPoints=V_regions; %Interior points for regions
inputStruct.holePoints=V_holes; %Interior points for holes
inputStruct.regionA=regionTetVolumes; %Desired tetrahedral volume for each region

% Mesh model using tetrahedral elements using tetGen
[meshOutput]=runTetGen(inputStruct); %Run tetGen
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- TETGEN Tetrahedral meshing --- 27-Nov-2023 11:03:09
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Writing SMESH file --- 27-Nov-2023 11:03:09
----> Adding node field
----> Adding facet field
----> Adding holes specification
----> Adding region specification
--- Done --- 27-Nov-2023 11:03:09
--- Running TetGen to mesh input boundary--- 27-Nov-2023 11:03:09
Opening /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.smesh.
Delaunizing vertices...
Delaunay seconds:  0.004136
Creating surface mesh ...
Surface mesh seconds:  0.001305
Recovering boundaries...
Boundary recovery seconds:  0.002196
Removing exterior tetrahedra ...
Spreading region attributes.
Exterior tets removal seconds:  0.001294
Recovering Delaunayness...
Delaunay recovery seconds:  0.00117
Refining mesh...
  2026 insertions, added 1596 points, 52838 tetrahedra in queue.
  674 insertions, added 520 points, 63961 tetrahedra in queue.
  899 insertions, added 644 points, 76346 tetrahedra in queue.
  1198 insertions, added 716 points, 85093 tetrahedra in queue.
  1597 insertions, added 594 points, 66637 tetrahedra in queue.
  2129 insertions, added 315 points, 1474 tetrahedra in queue.
Refinement seconds:  0.057252
Smoothing vertices...
Mesh smoothing seconds:  0.100056
Improving mesh...
Mesh improvement seconds:  0.003621

Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.node.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.ele.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.face.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.edge.

Output seconds:  0.013841
Total running seconds:  0.184971

Statistics:

  Input points: 1520
  Input facets: 3036
  Input segments: 4554
  Input holes: 0
  Input regions: 1

  Mesh points: 6065
  Mesh tetrahedra: 32735
  Mesh faces: 66988
  Mesh faces on exterior boundary: 3036
  Mesh faces on input facets: 3036
  Mesh edges on input segments: 4554
  Steiner points inside domain: 4545

--- Done --- 27-Nov-2023 11:03:10
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Importing TetGen files --- 27-Nov-2023 11:03:10
--- Done --- 27-Nov-2023 11:03:10

Access mesh output structure

E=meshOutput.elements; %The elements
V=meshOutput.nodes; %The vertices or nodes
CE=meshOutput.elementMaterialID; %Element material or region id
Fb=meshOutput.facesBoundary; %The boundary faces
Cb=meshOutput.boundaryMarker; %The boundary markers

Visualization

hf=cFigure;
subplot(1,2,1); hold on;
title('Input boundaries','FontSize',fontSize);
hp(1)=gpatch(Fb,V,Cb,'k',faceAlpha1);
hp(2)=plotV(V_regions,'r.','MarkerSize',markerSize);
legend(hp,{'Input mesh','Interior point(s)'},'Location','NorthWestOutside');
axisGeom(gca,fontSize); camlight headlight;
colormap(cMap); icolorbar;

hs=subplot(1,2,2); hold on;
title('Tetrahedral mesh','FontSize',fontSize);

% Visualizing using |meshView|
optionStruct.hFig=[hf,hs];
meshView(meshOutput,optionStruct);

axisGeom(gca,fontSize);
gdrawnow;

Example 2: Meshing imported geometry

Import an STL model

defaultFolder = fileparts(fileparts(mfilename('fullpath')));
pathName=fullfile(defaultFolder,'data','STL');
fileName=fullfile(pathName,'femur.stl');
[stlStruct] = import_STL(fileName);

F=stlStruct.solidFaces{1};
V=stlStruct.solidVertices{1};

% Merging nodes (nodes are not merged in stl)
[F,V]=mergeVertices(F,V);

C=ones(size(F,1),1); %Face boundary markers (aka face colors)
V_regions=getInnerPoint(F,V); %Define region points
V_holes=[]; %Define hole points
[regionTetVolumes]=tetVolMeanEst(F,V); %Volume estimate for regular tets
stringOpt='-pq1.2AaY'; %Options for tetgen

Mesh using TetGen

%Create tetgen input structure
inputStruct.stringOpt=stringOpt; %Tetgen options
inputStruct.Faces=F; %Boundary faces
inputStruct.Nodes=V; %Nodes of boundary
inputStruct.faceBoundaryMarker=C;
inputStruct.regionPoints=V_regions; %Interior points for regions
inputStruct.holePoints=V_holes; %Interior points for holes
inputStruct.regionA=regionTetVolumes; %Desired tetrahedral volume for each region

% Mesh model using tetrahedral elements using tetGen
[meshOutput]=runTetGen(inputStruct); %Run tetGen
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- TETGEN Tetrahedral meshing --- 27-Nov-2023 11:03:12
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Writing SMESH file --- 27-Nov-2023 11:03:12
----> Adding node field
----> Adding facet field
----> Adding holes specification
----> Adding region specification
--- Done --- 27-Nov-2023 11:03:12
--- Running TetGen to mesh input boundary--- 27-Nov-2023 11:03:12
Opening /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.smesh.
Delaunizing vertices...
Delaunay seconds:  0.008425
Creating surface mesh ...
Surface mesh seconds:  0.002832
Recovering boundaries...
Boundary recovery seconds:  0.005207
Removing exterior tetrahedra ...
Spreading region attributes.
Exterior tets removal seconds:  0.003143
Recovering Delaunayness...
Delaunay recovery seconds:  0.002812
Refining mesh...
  3951 insertions, added 2867 points, 96839 tetrahedra in queue.
  1315 insertions, added 812 points, 113061 tetrahedra in queue.
  1753 insertions, added 908 points, 127021 tetrahedra in queue.
  2337 insertions, added 881 points, 127570 tetrahedra in queue.
  3115 insertions, added 603 points, 79813 tetrahedra in queue.
  4152 insertions, added 443 points, 4844 tetrahedra in queue.
Refinement seconds:  0.115455
Smoothing vertices...
Mesh smoothing seconds:  0.156151
Improving mesh...
Mesh improvement seconds:  0.005784

Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.node.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.ele.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.face.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.edge.

Output seconds:  0.020849
Total running seconds:  0.320851

Statistics:

  Input points: 2964
  Input facets: 5924
  Input segments: 8886
  Input holes: 0
  Input regions: 1

  Mesh points: 9835
  Mesh tetrahedra: 51987
  Mesh faces: 106936
  Mesh faces on exterior boundary: 5924
  Mesh faces on input facets: 5924
  Mesh edges on input segments: 8886
  Steiner points inside domain: 6871

--- Done --- 27-Nov-2023 11:03:13
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Importing TetGen files --- 27-Nov-2023 11:03:13
--- Done --- 27-Nov-2023 11:03:13

Access mesh output structure

E=meshOutput.elements; %The elements
V=meshOutput.nodes; %The vertices or nodes
CE=meshOutput.elementMaterialID; %Element material or region id
Fb=meshOutput.facesBoundary; %The boundary faces
Cb=meshOutput.boundaryMarker; %The boundary markers

Visualization

hf=cFigure;
subplot(1,2,1); hold on;
title('Input boundaries','FontSize',fontSize);
hp(1)=gpatch(Fb,V,Cb,'k',faceAlpha1);
hp(2)=plotV(V_regions,'r.','MarkerSize',markerSize);
legend(hp,{'Input mesh','Interior point(s)'},'Location','NorthWestOutside');
axisGeom(gca,fontSize); camlight headlight;
colormap(cMap); icolorbar;

hs=subplot(1,2,2); hold on;
title('Tetrahedral mesh','FontSize',fontSize);

% Visualizing using |meshView|
optionStruct.hFig=[hf,hs];
meshView(meshOutput,optionStruct);

axisGeom(gca,fontSize);
gdrawnow;

Example 3: Meshing a two-region model

Create example geometry, here a torus containing a smaller torus

% An example surface
r=2; %Sphere radius
rc=3; %Central radius
nr=20;
nc=30;
ptype='tri';
[F1,V1]=patchTorus(r,nr,rc,nc,ptype);

r=1; %Sphere radius
rc=3; %Central radius
nr=15;
nc=25;
ptype='tri';
[F2,V2]=patchTorus(r,nr,rc,nc,ptype);

[F,V,C]=joinElementSets({F1 F2},{V1 V2}); %Join sets

[V_region1]=getInnerPoint(F(C==2,:),V); %First interior point
[V_region2]=getInnerPoint({F1,F2},{V1,V2}); %Second interior point
V_regions=[V_region1; V_region2]; %Collect region points
V_holes=[]; %Define hole points
[regionTetVolume1]=tetVolMeanEst(F1,V1); %Volume estimate for regular tets
[regionTetVolume2]=tetVolMeanEst(F2,V2); %Volume estimate for regular tets
regionTetVolumes=[regionTetVolume1 regionTetVolume2];
stringOpt='-pq1.2AaY'; %Tetgen options

mesh using tet

%Create tetgen input structure
inputStruct.stringOpt=stringOpt; %Tetgen options
inputStruct.Faces=F; %Boundary faces
inputStruct.Nodes=V; %Nodes of boundary
inputStruct.faceBoundaryMarker=C;
inputStruct.regionPoints=V_regions; %Interior points for regions
inputStruct.holePoints=V_holes; %Interior points for holes
inputStruct.regionA=regionTetVolumes; %Desired tetrahedral volume for each region

% Mesh model using tetrahedral elements using tetGen
[meshOutput]=runTetGen(inputStruct); %Run tetGen
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- TETGEN Tetrahedral meshing --- 27-Nov-2023 11:03:15
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Writing SMESH file --- 27-Nov-2023 11:03:15
----> Adding node field
----> Adding facet field
----> Adding holes specification
----> Adding region specification
--- Done --- 27-Nov-2023 11:03:15
--- Running TetGen to mesh input boundary--- 27-Nov-2023 11:03:15
Opening /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.smesh.
Delaunizing vertices...
Delaunay seconds:  0.035199
Creating surface mesh ...
Surface mesh seconds:  0.000822
Recovering boundaries...
Boundary recovery seconds:  0.001646
Removing exterior tetrahedra ...
Spreading region attributes.
Exterior tets removal seconds:  0.000491
Recovering Delaunayness...
Delaunay recovery seconds:  0.009777
Refining mesh...
  1299 insertions, added 591 points, 18366 tetrahedra in queue.
  432 insertions, added 84 points, 18074 tetrahedra in queue.
  576 insertions, added 86 points, 16168 tetrahedra in queue.
  768 insertions, added 77 points, 10876 tetrahedra in queue.
  1023 insertions, added 43 points, 68 tetrahedra in queue.
  1364 insertions, added 66 points, 914 tetrahedra in queue.
Refinement seconds:  0.027616
Smoothing vertices...
Mesh smoothing seconds:  0.021496
Improving mesh...
Mesh improvement seconds:  0.001122

Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.node.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.ele.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.face.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.edge.

Output seconds:  0.004161
Total running seconds:  0.102419

Statistics:

  Input points: 975
  Input facets: 1950
  Input segments: 2925
  Input holes: 0
  Input regions: 2

  Mesh points: 1946
  Mesh tetrahedra: 10190
  Mesh faces: 20980
  Mesh faces on exterior boundary: 1200
  Mesh faces on input facets: 1950
  Mesh edges on input segments: 2925
  Steiner points inside domain: 971

--- Done --- 27-Nov-2023 11:03:15
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Importing TetGen files --- 27-Nov-2023 11:03:15
--- Done --- 27-Nov-2023 11:03:15

Access mesh output structure

E=meshOutput.elements; %The elements
V=meshOutput.nodes; %The vertices or nodes
CE=meshOutput.elementMaterialID; %Element material or region id
Fb=meshOutput.facesBoundary; %The boundary faces
Cb=meshOutput.boundaryMarker; %The boundary markers

Visualization

hf=cFigure;
subplot(1,2,1); hold on;
title('Input boundaries','FontSize',fontSize);
hp(1)=gpatch(Fb,V,Cb,'k',faceAlpha1);
hp(2)=plotV(V_regions,'r.','MarkerSize',markerSize);
legend(hp,{'Input mesh','Interior point(s)'},'Location','NorthWestOutside');
axisGeom(gca,fontSize); camlight headlight;
colormap(cMap); icolorbar;

hs=subplot(1,2,2); hold on;
title('Tetrahedral mesh','FontSize',fontSize);

% Visualizing using |meshView|
optionStruct.hFig=[hf,hs];
meshView(meshOutput,optionStruct);

axisGeom(gca,fontSize);
gdrawnow;

Example 4: Meshing a multi-region model

Creating boundary surfaces

%Outer bunny
[F1,V1]=stanford_bunny('g'); %Bunny
V1_mean=mean(V1,1);
V1=V1-V1_mean(ones(size(V1,1),1),:);

%Inner bunny
V2=V1/4;
V2(:,3)=V2(:,3)-35;
V2(:,2)=V2(:,2)-15;
V2(:,1)=V2(:,1)+10;

V3=V1/4;
V3(:,3)=V3(:,3)-10;
V3(:,2)=V3(:,2)+10;
V3(:,1)=V3(:,1)+40;

%Joining surface sets
[F,V,C]=joinElementSets({F1,F1,F1},{V1,V2,V3});

Find interior points

[V_region1]=getInnerPoint({F1,F1,F1},{V1,V2,V3});
[V_region2]=getInnerPoint(F1,V2);
[V_region3]=getInnerPoint(F1,V3);
V_regions=[V_region1; V_region2; V_region3];

%Define hole points
V_holes=[];

% Volume parameters
[vol1]=tetVolMeanEst(F1,V1);
[vol2]=tetVolMeanEst(F1,V2);
[vol3]=tetVolMeanEst(F1,V3);

regionTetVolumes=[vol1 vol2 vol3]; %Element volume settings
stringOpt='-pq1.2AaY'; %Tetgen options

mesh using tet

%Create tetgen input structure
inputStruct.stringOpt=stringOpt; %Tetgen options
inputStruct.Faces=F; %Boundary faces
inputStruct.Nodes=V; %Nodes of boundary
inputStruct.faceBoundaryMarker=C;
inputStruct.regionPoints=V_regions; %Interior points for regions
inputStruct.holePoints=V_holes; %Interior points for holes
inputStruct.regionA=regionTetVolumes; %Desired tetrahedral volume for each region

% Mesh model using tetrahedral elements using tetGen
[meshOutput]=runTetGen(inputStruct); %Run tetGen
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- TETGEN Tetrahedral meshing --- 27-Nov-2023 11:03:19
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Writing SMESH file --- 27-Nov-2023 11:03:19
----> Adding node field
----> Adding facet field
----> Adding holes specification
----> Adding region specification
--- Done --- 27-Nov-2023 11:03:19
--- Running TetGen to mesh input boundary--- 27-Nov-2023 11:03:19
Opening /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.smesh.
Delaunizing vertices...
Delaunay seconds:  0.012558
Creating surface mesh ...
Surface mesh seconds:  0.004039
Recovering boundaries...
Boundary recovery seconds:  0.00768
Removing exterior tetrahedra ...
Spreading region attributes.
Exterior tets removal seconds:  0.002712
Recovering Delaunayness...
Delaunay recovery seconds:  0.006258
Refining mesh...
  6078 insertions, added 4879 points, 201347 tetrahedra in queue.
  2023 insertions, added 1455 points, 233749 tetrahedra in queue.
  2697 insertions, added 1889 points, 273453 tetrahedra in queue.
  3595 insertions, added 2282 points, 315106 tetrahedra in queue.
  4792 insertions, added 2396 points, 336371 tetrahedra in queue.
  6388 insertions, added 1906 points, 268161 tetrahedra in queue.
  8515 insertions, added 1250 points, 1796 tetrahedra in queue.
Refinement seconds:  0.273391
Smoothing vertices...
Mesh smoothing seconds:  0.48088
Improving mesh...
Mesh improvement seconds:  0.01455

Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.node.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.ele.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.face.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.edge.

Output seconds:  0.051165
Total running seconds:  0.853455

Statistics:

  Input points: 4560
  Input facets: 9108
  Input segments: 13662
  Input holes: 0
  Input regions: 3

  Mesh points: 21224
  Mesh tetrahedra: 126673
  Mesh faces: 254864
  Mesh faces on exterior boundary: 3036
  Mesh faces on input facets: 9108
  Mesh edges on input segments: 13662
  Steiner points inside domain: 16664

--- Done --- 27-Nov-2023 11:03:19
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Importing TetGen files --- 27-Nov-2023 11:03:19
--- Done --- 27-Nov-2023 11:03:20

Access mesh output structure

E=meshOutput.elements; %The elements
V=meshOutput.nodes; %The vertices or nodes
CE=meshOutput.elementMaterialID; %Element material or region id
Fb=meshOutput.facesBoundary; %The boundary faces
Cb=meshOutput.boundaryMarker; %The boundary markers

Visualization

hf=cFigure;
subplot(1,2,1); hold on;
title('Input boundaries','FontSize',fontSize);
hp(1)=gpatch(Fb,V,Cb,'k',faceAlpha1);
hp(2)=plotV(V_regions,'r.','MarkerSize',markerSize);
legend(hp,{'Input mesh','Interior point(s)'},'Location','NorthWestOutside');
axisGeom(gca,fontSize); camlight headlight;
colormap(cMap); icolorbar;

hs=subplot(1,2,2); hold on;
title('Tetrahedral mesh','FontSize',fontSize);

% Visualizing using |meshView|
optionStruct.hFig=[hf,hs];
meshView(meshOutput,optionStruct);

axisGeom(gca,fontSize);
gdrawnow;

Example 5: Meshing regions with holes

Simulating a multiregion mesh containing a void

[F1,V1]=parasaurolophus; %A dino

%An internal region
[F2,V2,~]=geoSphere(3,0.4);
V2(:,1)=2*V2(:,1)+0.6;
V2(:,3)=V2(:,3)+0.25;

%An internal hole
[F3,V3,~]=geoSphere(2,0.3);
V3(:,1)=V3(:,1)+0.6;
V3(:,3)=V3(:,3)+0.25;

%Joining surface sets
[F,V,C]=joinElementSets({F1,F2,F3},{V1,V2,V3});

Find interior points

[V_region1]=getInnerPoint({F1,F2,F3},{V1,V2,V3});
[V_region2]=getInnerPoint(F2,V2);
[V_holes]=getInnerPoint(F3,V3);

V_regions=[V_region1; V_region2];

% Volume parameters
[vol1]=tetVolMeanEst(F1,V1);
[vol2]=tetVolMeanEst(F2,V2);

regionTetVolumes=[vol1 vol2]; %Element volume settings
stringOpt='-pq1.2AaY'; %Tetgen options

mesh using tet

%Create tetgen input structure
inputStruct.stringOpt=stringOpt; %Tetgen options
inputStruct.Faces=F; %Boundary faces
inputStruct.Nodes=V; %Nodes of boundary
inputStruct.faceBoundaryMarker=C;
inputStruct.regionPoints=V_regions; %Interior points for regions
inputStruct.holePoints=V_holes; %Interior points for holes
inputStruct.regionA=regionTetVolumes; %Desired tetrahedral volume for each region

% Mesh model using tetrahedral elements using tetGen
[meshOutput]=runTetGen(inputStruct); %Run tetGen
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- TETGEN Tetrahedral meshing --- 27-Nov-2023 11:03:22
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Writing SMESH file --- 27-Nov-2023 11:03:22
----> Adding node field
----> Adding facet field
----> Adding holes specification
----> Adding region specification
--- Done --- 27-Nov-2023 11:03:22
--- Running TetGen to mesh input boundary--- 27-Nov-2023 11:03:22
Opening /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.smesh.
Delaunizing vertices...
Delaunay seconds:  0.019816
Creating surface mesh ...
Surface mesh seconds:  0.002146
Recovering boundaries...
Boundary recovery seconds:  0.004565
Removing exterior tetrahedra ...
Spreading region attributes.
Exterior tets removal seconds:  0.002047
Recovering Delaunayness...
Delaunay recovery seconds:  0.004048
Refining mesh...
  3452 insertions, added 2075 points, 68090 tetrahedra in queue.
  1149 insertions, added 447 points, 75231 tetrahedra in queue.
  1532 insertions, added 441 points, 78109 tetrahedra in queue.
  2042 insertions, added 384 points, 71670 tetrahedra in queue.
  2722 insertions, added 263 points, 45257 tetrahedra in queue.
  3628 insertions, added 247 points, 2820 tetrahedra in queue.
  4836 insertions, added 313 points, 598 tetrahedra in queue.
Refinement seconds:  0.091261
Smoothing vertices...
Mesh smoothing seconds:  0.091693
Improving mesh...
Mesh improvement seconds:  0.004078

Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.node.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.ele.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.face.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.edge.

Output seconds:  0.014254
Total running seconds:  0.234057

Statistics:

  Input points: 2590
  Input facets: 5168
  Input segments: 7752
  Input holes: 1
  Input regions: 2

  Mesh points: 6887
  Mesh tetrahedra: 36644
  Mesh faces: 75232
  Mesh faces on exterior boundary: 3888
  Mesh faces on input facets: 5168
  Mesh edges on input segments: 7752
  Steiner points inside domain: 4297

--- Done --- 27-Nov-2023 11:03:23
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Importing TetGen files --- 27-Nov-2023 11:03:23
--- Done --- 27-Nov-2023 11:03:23

Access mesh output structure

E=meshOutput.elements; %The elements
V=meshOutput.nodes; %The vertices or nodes
CE=meshOutput.elementMaterialID; %Element material or region id
Fb=meshOutput.facesBoundary; %The boundary faces
Cb=meshOutput.boundaryMarker; %The boundary markers

Visualization

hf=cFigure;
subplot(1,2,1); hold on;
title('Input boundaries','FontSize',fontSize);
hp(1)=gpatch(Fb,V,Cb,'k',faceAlpha1);
hp(2)=plotV(V_regions,'r.','MarkerSize',markerSize);
hp(3)=plotV(V_holes,'g.','MarkerSize',markerSize);
legend(hp,{'Input mesh','Interior point(s)','Hole point(s)'},'Location','NorthWestOutside');
axisGeom(gca,fontSize); camlight headlight;
colormap(cMap); icolorbar;

hs=subplot(1,2,2); hold on;
title('Tetrahedral mesh','FontSize',fontSize);

% Visualizing using |meshView|
optionStruct.hFig=[hf,hs];
meshView(meshOutput,optionStruct);

axisGeom(gca,fontSize);
gdrawnow;

Example 6: Meshing from a quadrilateral input surface

Build a quadrilateral surface

boxDim =[12 2 3];
boxEl  =[12 2 3];
[F,V,C]=quadBox(boxDim,boxEl);

regionTetVolumes=tetVolMeanEst(F,V);
V_regions=mean(V,1);
stringOpt='-pq1.2AaY'; %Tetgen options
V_holes=[];

Mesh using TetGen

%Create tetgen input structure
inputStruct.stringOpt=stringOpt; %Tetgen options
inputStruct.Faces=F; %Boundary faces
inputStruct.Nodes=V; %Nodes of boundary
inputStruct.faceBoundaryMarker=C;
inputStruct.regionPoints=V_regions; %Interior points for regions
inputStruct.holePoints=V_holes; %Interior points for holes
inputStruct.regionA=regionTetVolumes; %Desired tetrahedral volume for each region

% Mesh model using tetrahedral elements using tetGen
[meshOutput]=runTetGen(inputStruct); %Run tetGen
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- TETGEN Tetrahedral meshing --- 27-Nov-2023 11:03:25
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Writing SMESH file --- 27-Nov-2023 11:03:25
----> Adding node field
----> Adding facet field
----> Adding holes specification
----> Adding region specification
--- Done --- 27-Nov-2023 11:03:25
--- Running TetGen to mesh input boundary--- 27-Nov-2023 11:03:25
Opening /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.smesh.
Delaunizing vertices...
Delaunay seconds:  0.00162
Creating surface mesh ...
Surface mesh seconds:  0.000295
Recovering boundaries...
Boundary recovery seconds:  0.001106
Removing exterior tetrahedra ...
Spreading region attributes.
Exterior tets removal seconds:  4.7e-05
Recovering Delaunayness...
Delaunay recovery seconds:  0.001016
Refining mesh...
  178 insertions, added 49 points, 1216 tetrahedra in queue.
  59 insertions, added 7 points, 999 tetrahedra in queue.
  78 insertions, added 2 points, 424 tetrahedra in queue.
  104 insertions, added 8 points, 168 tetrahedra in queue.
  139 insertions, added 9 points, 84 tetrahedra in queue.
Refinement seconds:  0.002885
Smoothing vertices...
Mesh smoothing seconds:  0.003805
Improving mesh...
Mesh improvement seconds:  9.9e-05

Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.node.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.ele.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.face.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.edge.

Output seconds:  0.000424
Total running seconds:  0.011347

Statistics:

  Input points: 134
  Input facets: 132
  Input segments: 264
  Input holes: 0
  Input regions: 1

  Mesh points: 217
  Mesh tetrahedra: 836
  Mesh faces: 1804
  Mesh faces on exterior boundary: 264
  Mesh faces on input facets: 264
  Mesh edges on input segments: 264
  Steiner points inside domain: 83

--- Done --- 27-Nov-2023 11:03:25
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Importing TetGen files --- 27-Nov-2023 11:03:25
--- Done --- 27-Nov-2023 11:03:25

Access mesh output structure

E=meshOutput.elements; %The elements
V=meshOutput.nodes; %The vertices or nodes
CE=meshOutput.elementMaterialID; %Element material or region id
Fb=meshOutput.facesBoundary; %The boundary faces
Cb=meshOutput.boundaryMarker; %The boundary markers

Visualization

hf=cFigure;
subplot(1,2,1); hold on;
title('Input boundaries','FontSize',fontSize);
hp(1)=gpatch(F,V,C,'k',faceAlpha1);
hp(2)=plotV(V_regions,'r.','MarkerSize',markerSize);
legend(hp,{'Input mesh','Interior point(s)'},'Location','NorthWestOutside');
axisGeom(gca,fontSize); camlight headlight;
colormap(cMap); icolorbar;

hs=subplot(1,2,2); hold on;
title('Tetrahedral mesh','FontSize',fontSize);

% Visualizing using |meshView|
optionStruct.hFig=[hf,hs];
meshView(meshOutput,optionStruct);

axisGeom(gca,fontSize);
gdrawnow;
Warning: Ignoring extra legend entries. 

Example 7: Specifying a sizing function to control local mesh density

Build example geometry

boxDim =[12 2 3];
boxEl  =[12 2 3];
[F,V,C]=quadBox(boxDim,boxEl);
V_input=V;

Defining a size function on the boundary nodes

%Get edge lengths and base minimum size on input edge lengths
[edgeLengths]=patchEdgeLengths(F,V);
minEdgeSize=mean(edgeLengths)/5; %The smallest element size

n=5; %The largest element edge length is n times minEdgeSize
edgeSizeField=V(:,1);
edgeSizeField=edgeSizeField-min(edgeSizeField(:));
edgeSizeField=edgeSizeField./max(edgeSizeField(:));
edgeSizeField=(edgeSizeField*(n-1))+1; %Range from 0-n depending on V(:,1) i.e. X-dir
edgeSizeField=(edgeSizeField*minEdgeSize);

regionTetVolumes=tetVolMeanEst(F,V);
V_regions=mean(V,1);
stringOpt='-pq1.2Aa'; %Tetgen options
V_holes=[];

Mesh using TetGen

%Create tetgen input structure
inputStruct.stringOpt=stringOpt; %Tetgen options
inputStruct.Faces=F; %Boundary faces
inputStruct.Nodes=V; %Nodes of boundary
inputStruct.faceBoundaryMarker=C;
inputStruct.regionPoints=V_regions; %Interior points for regions
inputStruct.holePoints=V_holes; %Interior points for holes
inputStruct.regionA=regionTetVolumes; %Desired tetrahedral volume for each region
inputStruct.sizeData=edgeSizeField; %The size data

% Mesh model using tetrahedral elements using tetGen
[meshOutput]=runTetGen(inputStruct); %Run tetGen
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- TETGEN Tetrahedral meshing --- 27-Nov-2023 11:03:27
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Writing SMESH file --- 27-Nov-2023 11:03:27
----> Adding node field
----> Adding facet field
----> Adding holes specification
----> Adding region specification
--- Done --- 27-Nov-2023 11:03:27
--- Writing MTR file --- 27-Nov-2023 11:03:27
--- Running TetGen to mesh initial Delaunay tesselation using sizing function--- 27-Nov-2023 11:03:27
Opening /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.smesh.
Opening /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.mtr.
  Cannot access file /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.b.node.
Delaunizing vertices...
Delaunay seconds:  0.001552
Creating surface mesh ...
Surface mesh seconds:  0.000299
Recovering boundaries...
Boundary recovery seconds:  0.001048
Removing exterior tetrahedra ...
Spreading region attributes.
Exterior tets removal seconds:  6.4e-05
Mesh coarsening ...
Mesh coarsening seconds:  1e-06
Recovering Delaunayness...
Delaunay recovery seconds:  0.000945
Refining mesh...
  178 insertions, added 111 points, 2184 tetrahedra in queue.
  59 insertions, added 38 points, 2770 tetrahedra in queue.
  78 insertions, added 49 points, 3452 tetrahedra in queue.
  104 insertions, added 73 points, 4701 tetrahedra in queue.
  139 insertions, added 92 points, 6154 tetrahedra in queue.
  185 insertions, added 124 points, 8181 tetrahedra in queue.
  247 insertions, added 178 points, 11206 tetrahedra in queue.
  329 insertions, added 228 points, 14867 tetrahedra in queue.
  439 insertions, added 294 points, 16828 tetrahedra in queue.
Refinement seconds:  0.014634
Smoothing vertices...
Mesh smoothing seconds:  0.021465
Improving mesh...
Mesh improvement seconds:  0.000687

Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.node.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.ele.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.face.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.edge.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.mtr.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.p2t.

Output seconds:  0.002907
Total running seconds:  0.043644

Statistics:

  Input points: 134
  Input facets: 132
  Input segments: 68
  Input holes: 0
  Input regions: 1

  Mesh points: 1406
  Mesh tetrahedra: 6194
  Mesh faces: 13133
  Mesh faces on exterior boundary: 1490
  Mesh faces on input facets: 1490
  Mesh edges on input segments: 131
  Steiner points on input facets:  550
  Steiner points on input segments:  63
  Steiner points inside domain: 659

--- Done --- 27-Nov-2023 11:03:27
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Importing TetGen files --- 27-Nov-2023 11:03:27
--- Done --- 27-Nov-2023 11:03:27

Access mesh output structure

E=meshOutput.elements; %The elements
V=meshOutput.nodes; %The vertices or nodes
CE=meshOutput.elementMaterialID; %Element material or region id
Fb=meshOutput.facesBoundary; %The boundary faces
Cb=meshOutput.boundaryMarker; %The boundary markers

Visualization

hf=cFigure;
subplot(1,2,1); hold on;
title('Input boundaries','FontSize',fontSize);
hp(1)=gpatch(F,V,'kw','none',faceAlpha1);
hp(2)=plotV(V_regions,'r.','MarkerSize',markerSize);
hp(3)=scatterV(V_input,75,edgeSizeField,'fill');
legend(hp,{'Input mesh','Interior point(s)','Sizing function points'},'Location','NorthWestOutside');
axisGeom(gca,fontSize); camlight headlight;
colormap(cMap); colorbar;
hs=subplot(1,2,2); hold on;
title('Tetrahedral mesh','FontSize',fontSize);

% Visualizing using |meshView|
optionStruct.hFig=[hf,hs];
meshView(meshOutput,optionStruct);

axisGeom(gca,fontSize);
gdrawnow;

clear hp;

Example 8: Meshing of topology with holes and complex regions

Simulating nested spheres with a hollow core and "tunnel" to outside

w=0.25;
r=0.1;

[Fs1,Vs1]=geoSphere(4,1);
[Fs2,Vs2]=geoSphere(4,1-w);
[Fs3,Vs3]=geoSphere(4,1-2*w);

R=sqrt(sum(Vs1(:,[1 2]).^2,2));
logicCropVertices=R<=(r+mean(patchEdgeLengths(Fs1,Vs1))) & Vs1(:,3)>0;
logicCropFaces=any(logicCropVertices(Fs1),2);
logicCropFaces=triSurfLogicSharpFix(Fs1,logicCropFaces);

Fs1=Fs1(~logicCropFaces,:);
Fs2=Fs2(~logicCropFaces,:);
Fs3=Fs3(~logicCropFaces,:);

Eb=patchBoundary(Fs1);
indB=edgeListToCurve(Eb);
indB=indB(1:end-1);

cPar.closeLoopOpt=1;
cPar.patchType='tri_slash';
[Fs4,Vs4]=polyLoftLinear(Vs3(indB,:),Vs2(indB,:),cPar);
[Fs5,Vs5]=polyLoftLinear(Vs2(indB,:),Vs1(indB,:),cPar);

[F,V,C]=joinElementSets({Fs1,Fs2,Fs3,Fs4,Fs5},{Vs1,Vs2,Vs3,Vs4,Vs5});
[F,V]=mergeVertices(F,V);
[F,V]=patchCleanUnused(F,V);

logicRegion1=ismember(C,[1 2 max(C(:))]);
logicRegion2=ismember(C,[2 3 4]);

V_inner1=getInnerPoint(F(logicRegion1,:),V);
V_inner2=getInnerPoint(F(logicRegion2,:),V);

V_regions=[V_inner1; V_inner2];

regionTetVolumes=tetVolMeanEst(F,V);
stringOpt='-pq1.2AaY'; %Tetgen options
V_holes=[];

Mesh using TetGen

%Create tetgen input structure
inputStruct.stringOpt=stringOpt; %Tetgen options
inputStruct.Faces=F; %Boundary faces
inputStruct.Nodes=V; %Nodes of boundary
inputStruct.faceBoundaryMarker=C;
inputStruct.regionPoints=V_regions; %Interior points for regions
inputStruct.holePoints=V_holes; %Interior points for holes
inputStruct.regionA=regionTetVolumes*ones(size(V_regions,1),1); %Desired tetrahedral volume for each region

% Mesh model using tetrahedral elements using tetGen
[meshOutput]=runTetGen(inputStruct); %Run tetGen
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- TETGEN Tetrahedral meshing --- 27-Nov-2023 11:03:29
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Writing SMESH file --- 27-Nov-2023 11:03:29
----> Adding node field
----> Adding facet field
----> Adding holes specification
----> Adding region specification
--- Done --- 27-Nov-2023 11:03:30
--- Writing MTR file --- 27-Nov-2023 11:03:30
--- Running TetGen to mesh initial Delaunay tesselation using sizing function--- 27-Nov-2023 11:03:30
Opening /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.smesh.
Opening /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.mtr.
  !! Point numbers are not equal. Ignored.
  Cannot access file /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.b.node.
Delaunizing vertices...
Delaunay seconds:  0.389077
Creating surface mesh ...
Surface mesh seconds:  0.006836
Recovering boundaries...
Boundary recovery seconds:  0.02056
Removing exterior tetrahedra ...
Spreading region attributes.
Exterior tets removal seconds:  0.004188
Mesh coarsening ...
Mesh coarsening seconds:  3.1e-05
Recovering Delaunayness...
Delaunay recovery seconds:  0.129384
Refining mesh...
  10361 insertions, added 9297 points, 334556 tetrahedra in queue.
  3450 insertions, added 2824 points, 398524 tetrahedra in queue.
  4599 insertions, added 3745 points, 479417 tetrahedra in queue.
  6130 insertions, added 4698 points, 575136 tetrahedra in queue.
  8171 insertions, added 5689 points, 675937 tetrahedra in queue.
  10892 insertions, added 5922 points, 715058 tetrahedra in queue.
  14519 insertions, added 4609 points, 355526 tetrahedra in queue.
  19354 insertions, added 2248 points, 22150 tetrahedra in queue.
Refinement seconds:  0.711101
Smoothing vertices...
Mesh smoothing seconds:  1.615
Improving mesh...
Mesh improvement seconds:  0.032621

Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.node.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.ele.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.face.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.edge.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.mtr.
Writing /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.1.p2t.

Output seconds:  0.112968
Total running seconds:  3.02214

Statistics:

  Input points: 7773
  Input facets: 15558
  Input segments: 23328
  Input holes: 0
  Input regions: 2

  Mesh points: 47291
  Mesh tetrahedra: 275949
  Mesh faces: 557144
  Mesh faces on exterior boundary: 10492
  Mesh faces on input facets: 15558
  Mesh edges on input segments: 23328
  Steiner points inside domain: 39518

--- Done --- 27-Nov-2023 11:03:33
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Importing TetGen files --- 27-Nov-2023 11:03:33
--- Done --- 27-Nov-2023 11:03:33

Access mesh output structure

E=meshOutput.elements; %The elements
V=meshOutput.nodes; %The vertices or nodes
CE=meshOutput.elementMaterialID; %Element material or region id
Fb=meshOutput.facesBoundary; %The boundary faces
Cb=meshOutput.boundaryMarker; %The boundary markers

Visualization

hf=cFigure;
subplot(1,2,1); hold on;
title('Input boundaries','FontSize',fontSize);
hp(1)=gpatch(F,V,'kw','none',faceAlpha1);
hp(2)=plotV(V_regions,'r.','MarkerSize',markerSize);
legend(hp,{'Input mesh','Interior point(s)'},'Location','NorthWestOutside');
axisGeom(gca,fontSize); camlight headlight;
colormap(cMap); colorbar;
hs=subplot(1,2,2); hold on;
title('Tetrahedral mesh','FontSize',fontSize);

% Visualizing using |meshView|
optionStruct.hFig=[hf,hs];
meshView(meshOutput,optionStruct);

axisGeom(gca,fontSize);
gdrawnow;

clear hp;

Example 9: Meshing 10-node (i.e. quadratic) tetrahedral elements

% Building spherical surface models
[F,V,~]=geoSphere(2,1);
C=ones(size(F,1),1);
V_regions=[0 0 0];
V_holes=[];
regionTetVolumes=tetVolMeanEst(F,V);
stringOpt='-pq1.2AaYQ';

Mesh using TetGen

%Create tetgen input structure
inputStruct.stringOpt=stringOpt; %Tetgen options
inputStruct.Faces=F; %Boundary faces
inputStruct.Nodes=V; %Nodes of boundary
inputStruct.faceBoundaryMarker=C;
inputStruct.regionPoints=V_regions; %Interior points for regions
inputStruct.holePoints=V_holes; %Interior points for holes
inputStruct.regionA=regionTetVolumes; %Desired tetrahedral volume for each region
inputStruct.tetType='tet10'; %Set desired element type

% Mesh model using tetrahedral elements using tetGen
[meshOutput]=runTetGen(inputStruct); %Run tetGen
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- TETGEN Tetrahedral meshing --- 27-Nov-2023 11:03:36
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Writing SMESH file --- 27-Nov-2023 11:03:36
----> Adding node field
----> Adding facet field
----> Adding holes specification
----> Adding region specification
--- Done --- 27-Nov-2023 11:03:36
--- Writing MTR file --- 27-Nov-2023 11:03:36
--- Running TetGen to mesh initial Delaunay tesselation using sizing function--- 27-Nov-2023 11:03:36
Opening /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.smesh.
Opening /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.mtr.
  !! Point numbers are not equal. Ignored.
  Cannot access file /home/kevin/DATA/Code/matlab/GIBBON/data/temp/temp.b.node.
--- Done --- 27-Nov-2023 11:03:36
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- Importing TetGen files --- 27-Nov-2023 11:03:36
--- Done --- 27-Nov-2023 11:03:36

Access mesh output structure

E=meshOutput.elements; %The elements
V=meshOutput.nodes; %The vertices or nodes
CE=meshOutput.elementMaterialID; %Element material or region id
Fb=meshOutput.facesBoundary; %The boundary faces
Cb=meshOutput.boundaryMarker; %The boundary markers

Visualization

%Selecting half of the model to see interior
Y=V(:,2); YE=mean(Y(E),2);
logicCutView=YE>mean(Y);
[Fs,Cs]=element2patch(E(logicCutView,:),CE(logicCutView),'tet10');

hf=cFigure;
subplot(1,2,1); hold on;
title('Input boundaries','FontSize',fontSize);
hp(1)=gpatch(F,V,C,'k',faceAlpha1);
hp(2)=plotV(V_regions,'r.','MarkerSize',markerSize);
legend(hp,{'Input mesh','Interior point(s)'},'Location','NorthWestOutside');
axisGeom(gca,fontSize); camlight headlight;
colormap(cMap); icolorbar;

hs=subplot(1,2,2); hold on;
title('Tetrahedral mesh','FontSize',fontSize);

title('Cut view of tetrahedral mesh model','FontSize',fontSize);
gpatch(Fb,V,0.5*ones(1,3),'none',faceAlpha1);
gpatch(Fs,V,Cs,'k',faceAlpha2);
% patchNormPlot(Fs,V);

plotV(V(unique(Fs(:)),:),'k.','MarkerSize',markerSize);
camlight headlight;
axisGeom(gca,fontSize);
colormap(cMap);
gdrawnow;

GIBBON www.gibboncode.org

Kevin Mattheus Moerman, [email protected]

GIBBON footer text

License: https://github.com/gibbonCode/GIBBON/blob/master/LICENSE

GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for image segmentation, image-based modeling, meshing, and finite element analysis.

Copyright (C) 2006-2023 Kevin Mattheus Moerman and the GIBBON contributors

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.