# triplyPeriodicMinimal

Below is a demonstration of the features of the triplyPeriodicMinimal function

## Contents

```clear; close all; clc;
```

## Syntax

S=triplyPeriodicMinimal(X,Y,Z,typeStr);

## Description

This function creates the image S which can be used to define triply periodic minimal surfaces. The input consists of a grid of coordinates (X,Y,Z) and the surface type (typeStr).

## Examples

```clear; close all; clc;
```

Plot settings

```cMap=jet(250);
faceAlpha1=1;
faceAlpha2=0.65;
edgeColor1='none';
edgeColor2='none';
fontSize=25;
pColors=gjet(6);
```

## Example: Construct triply periodic minimal surfaces

```%Create a grid
n=35;
[X,Y,Z]=meshgrid(linspace(-pi,pi,n));

%Evaluate triply periodic function
S=triplyPeriodicMinimal(X,Y,Z,'p');

%Construct iso-surface
[F,V] = isosurface(X,Y,Z,S,0);
```

Visualize surface

```cFigure;
hold on;
title('Schwarz P-surface','FontSize',fontSize);
gpatch(F,V,'kw','k',1);
axisGeom;
drawnow;
```

Visualization all variations

```cFigure;

subplot(2,3,1);
title('Schwarz P-surface','FontSize',fontSize);
hold on;
gpatch(F,V,pColors(1,:),'none',1);
axisGeom;
view(-50,30);

[X,Y,Z]=meshgrid(linspace(-pi,pi,n));
S=triplyPeriodicMinimal(X,Y,Z,'d');
[F,V] = isosurface(X,Y,Z,S,0.1);

subplot(2,3,2);
title('d','FontSize',fontSize);
hold on;
gpatch(F,V,pColors(2,:),'none',1);
axisGeom;
view(-50,30);

[X,Y,Z]=meshgrid(linspace(-2*pi,2*pi,n));
S=triplyPeriodicMinimal(X,Y,Z,'g');
[F,V] = isosurface(X,Y,Z,S,0.6);

subplot(2,3,3);
title('Gyroid','FontSize',fontSize);
hold on;
gpatch(F,V,pColors(3,:),'none',1);
axisGeom;
view(-50,30);

[X,Y,Z]=meshgrid(linspace(-pi,pi,n));
S=triplyPeriodicMinimal(X,Y,Z,'n');
[F,V] = isosurface(X,Y,Z,S,0);

subplot(2,3,4);
title('Neovius','FontSize',fontSize);
hold on;
gpatch(F,V,pColors(4,:),'none',1);
axisGeom;
view(-50,30);

[X,Y,Z]=meshgrid(linspace(-pi,pi,n));
S=triplyPeriodicMinimal(X,Y,Z,'w');
[F,V] = isosurface(X,Y,Z,S,0);

subplot(2,3,5);
title('w','FontSize',fontSize);
hold on;
gpatch(F,V,pColors(5,:),'none',1);
axisGeom;
view(-50,30);

[X,Y,Z]=meshgrid(linspace(-pi,pi,n));
S=triplyPeriodicMinimal(X,Y,Z,'pw');
[F,V] = isosurface(X,Y,Z,S,0.5);

subplot(2,3,6);
title('pw','FontSize',fontSize);
hold on;
gpatch(F,V,pColors(6,:),'none',1);
axisGeom;
view(-50,30);

drawnow;
```

## Example: Creating a hexahedral mesh of for a regular trabecular structure

This example renders boundary faces. Use the 'h' option for im2patch to obtain hexehadral elements.

```n=50;
[X,Y,Z]=meshgrid(linspace(-2*pi,2*pi,n));
S=triplyPeriodicMinimal(X,Y,Z,'g');

T=0.6;
c=(max(S(:))*T);
L=S>=c;
[F1,V1,C1]=im2patch(S,L,'vb');

L=S<c;
[F2,V2,C2]=im2patch(S,L,'vb');
```

Visualization

```cFigure;
subplot(1,2,1);
title('Gyroid based "network"','FontSize',fontSize);
xlabel('J','FontSize',fontSize);ylabel('I','FontSize',fontSize); zlabel('K','FontSize',fontSize); hold on;
gpatch(F1,V1,C1,'k',1);
axisGeom;
colormap(cMap);
caxis([min(S(:)) max(S(:))]);

subplot(1,2,2);
title('Gyroid based "matrix"','FontSize',fontSize);
xlabel('J','FontSize',fontSize);ylabel('I','FontSize',fontSize); zlabel('K','FontSize',fontSize); hold on;
gpatch(F2,V2,C2,'k',1);
axisGeom;
colormap(cMap);
caxis([min(S(:)) max(S(:))]);

drawnow;
```

## Example: Thickening the surfaces

```n=75;
typeStr='g';
switch typeStr
case 'p'
[X,Y,Z]=meshgrid(linspace(-pi,pi,n));
S=triplyPeriodicMinimal(X,Y,Z,'p');
[F,V] = isosurface(X,Y,Z,S,0);
case 'g'
[X,Y,Z]=meshgrid(linspace(-1.9*pi,1.9*pi,n));
S=triplyPeriodicMinimal(X,Y,Z,'g');
[F,V] = isosurface(X,Y,Z,S,0);
V=V./max(V(:)); %Normalize coordinates
V=V*45/2;
end
F1=F; V1=V; %Store originals

%Get boundary edges
Eb=patchBoundary(F,V);

% %Smoothen surface
% controlPar.Method='HC';
% controlPar.n=5;
% controlPar.RigidConstraints=unique(Eb(:));
% V=patchSmooth(F,V,[],controlPar);
```

Thicken surface in ward

```thicknessOffset=1; %The desired thickness
[~,~,N]=patchNormal(F,V); %Vertex normal vectors
V1=V-N*thicknessOffset/2; %The offset coordinates
V2=V+N*thicknessOffset/2; %The offset coordinates
numVertices=size(V,1);
V=[V1;V2]; %Append new coordinates
F=[F;fliplr(F)+numVertices]; %Append new faces (note offset in indices)
Ebb=[Eb;Eb+numVertices];
```

Close boundary features

```optionStruct.outputType='label';
G=tesgroup(Eb,optionStruct); %grouping of boundary edges

for q=1:1:max(G(:))
logicGroup=(G==q);
Eb_now=Eb(logicGroup,:);
f=[fq(:,[1 2 3]); fq(:,[3 4 1]);]; %New triangular faces
F=[F;fliplr(f)]; %Append new faces
end

[F,V,~,ind2]=mergeVertices(F,V);
Ebb=ind2(Ebb);

logic1=V(:,3)<(-45/2+0.1);
V(logic1,3)=-45/2;
```

Visualize thickened surface

```cFigure;
hold on; hold on;
title('Thickened  surface','FontSize',fontSize);
gpatch(F,V,'bw','none',1);
gpatch(Ebb,V,'none','b',0,2);
% patchNormPlot(F,V); %Visualize face normal directions
axisGeom;
drawnow;
```

The model can be exported to an STL file using export_STL_txt, see HELP_export_STL_txt.

GIBBON www.gibboncode.org

Kevin Mattheus Moerman, [email protected]

GIBBON footer text

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