Skip to content

Commit

Permalink
Uploaded code content and initial documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin-Mattheus-Moerman committed Sep 1, 2021
1 parent ecc648e commit 033dde5
Show file tree
Hide file tree
Showing 50 changed files with 3,589 additions and 0 deletions.
926 changes: 926 additions & 0 deletions data/BodyParts3D/FMA_ID_label_obj.csv

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions data/BodyParts3D/LICENSE_content
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Summary: Creative Commons License Creative Commons Attribution-Inheritance 2.1 Japan (CC BY-SA)

Original: http://lifesciencedb.jp/bp3d/info_en/license/index.html

Translation: https://creativecommons.org/licenses/by-sa/2.1/jp/deed.en

About terms of use and credit description:
The standard licenses for the contents (including images created by Anatomography) published on this site (http://lifesciencedb.jp/bp3d, http://lifesciencedb.jp/ag) are as follows.

Creative Commons License Creative Commons Attribution-Inheritance 2.1 Japan

Please be sure to display the following credits before using.

BodyParts3D, Copyrightc 2008 Life Science Integrated Database Center licensed by CC Display-Inheritance 2.1 Japan
Binary file added data/BodyParts3D/mat/FMA16586.mat
Binary file not shown.
Binary file added data/BodyParts3D/mat/FMA24474.mat
Binary file not shown.
Binary file added data/BodyParts3D/mat/FMA24477.mat
Binary file not shown.
Binary file added data/BodyParts3D/mat/FMA24480.mat
Binary file not shown.
Binary file added data/BodyParts3D/mat/FMA24486.mat
Binary file not shown.
Binary file added data/BodyParts3D/mat/FMA7163.mat
Binary file not shown.
Binary file added data/BodyParts3D/post/right_femur.mat
Binary file not shown.
Binary file added data/BodyParts3D/post/right_fibula.mat
Binary file not shown.
Binary file added data/BodyParts3D/post/right_hip_bone.mat
Binary file not shown.
Binary file added data/BodyParts3D/post/right_leg_skin.mat
Binary file not shown.
Binary file added data/BodyParts3D/post/right_patella.mat
Binary file not shown.
Binary file added data/BodyParts3D/post/right_tibia.mat
Binary file not shown.
Binary file added data/BodyParts3D/post/skin_leg_right.mat
Binary file not shown.
Binary file added data/BodyParts3D/stl/FMA16586.stl
Binary file not shown.
Binary file added data/BodyParts3D/stl/FMA24474.stl
Binary file not shown.
Binary file added data/BodyParts3D/stl/FMA24477.stl
Binary file not shown.
Binary file added data/BodyParts3D/stl/FMA24480.stl
Binary file not shown.
Binary file added data/BodyParts3D/stl/FMA24486.stl
Binary file not shown.
Binary file added data/BodyParts3D/stl/FMA7163.stl
Binary file not shown.
69 changes: 69 additions & 0 deletions mcode/A_BodyParts3D_convert_STL_to_MAT.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
clear; close all; clc;

%% Description
% This code parses all STL files in the /stl folder and exports them as MAT
% files to the /mat folder.
%
% This code requires the GIBBON MATLAB toolbox
% <www.gibboncode.org>

%% Control parameters

% Path names
projectFolder = fileparts(fileparts(mfilename('fullpath'))); %Main code path
loadFolder=fullfile(projectFolder,'data','BodyParts3D','stl'); %The STL loading folder
saveFolder=fullfile(projectFolder,'data','BodyParts3D','mat'); %The MAT saving folder

%%

%Get list of all STL files
fileList = dir(fullfile(loadFolder,['*','stl']));
fileList={fileList(1:end).name};

Dc=readtable(fullfile(projectFolder,'data','BodyParts3D','FMA_ID_label_obj.csv'));
P=lower(Dc.FMAID);

%Convert all STL files to MAT
numFiles=numel(fileList); %Number of files to parse
for q=1:1:numFiles %Loop over all files
%Get file name
[~,fileNameClean,~]=fileparts(fileList{q}); %File name without path or extension

%Prepare STL file name
fileNameLoad=fullfile(loadFolder,fileList{q}); %STL file name

%Prepare save file name
fileNameSave=fullfile(saveFolder,[fileNameClean,'.mat']); %MAT file name

%Get FMAID code
FMAID=sscanf(fileNameClean,'FMA%d');

%Get preferred name
logicFMAID=P==FMAID;
preferredName=Dc.preferredName{logicFMAID};

%Parse STL import
disp(['Parsing file ', num2str(q),' of ',num2str(numFiles),', ',sprintf('%3.0f',round(100*q/numFiles)),'% done, ',fileNameClean,', ',preferredName])
try %MATLAB's stlread
TR = stlread(fileNameLoad);
v=TR.Points;
f=TR.ConnectivityList;
catch %GIBBON's importer
[stlStruct] = import_STL_bin(fileNameLoad);
v=stlStruct.solidVertices{1};
f=stlStruct.solidFaces{1};
end

%Merge vertices
[f,v]=mergeVertices(f,v);

%Build model structure
model.sourceName=fileList{q};
model.preferredName=preferredName;
model.faces=f;
model.vertices=v;

%Export MAT file
save(fileNameSave,'-struct','model');
end

76 changes: 76 additions & 0 deletions mcode/B_BodyParts3D_remesh_surfaces.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
clear; close all; clc;

%% Description
% This code parses a selection of MAT files in the /mat folder for surface
% meshes, and remeshes them at a desired point spacing. The remeshed
% surfaces are exported to the /post folder.
%
% This code requires the GIBBON MATLAB toolbox
% <www.gibboncode.org>

%% Plotting settings
lineWidth=0.5;

%% Control parameters

% Path names
projectFolder = fileparts(fileparts(mfilename('fullpath'))); %Main code path
loadFolder=fullfile(projectFolder,'data','BodyParts3D','mat'); %The MAT loading folder
saveFolder=fullfile(projectFolder,'data','BodyParts3D','post'); %The MAT saving folder for processed data

fileNames_FMA={'FMA16586','FMA24474','FMA24477','FMA24480','FMA24486'};

pointSpacings=[4 4 4 3 3];

optionStructRemesh.disp_on=0; % Turn off command window text display

saveOn=0;

%%

for q=1:1:numel(fileNames_FMA)

%% Import mesh
fileName_FMA=fileNames_FMA{q};
fileName_mat=fullfile(loadFolder,[fileName_FMA,'.mat']);

model=load(fileName_mat);
F=model.faces;
V=model.vertices;

%% Remesh
optionStructRemesh.pointSpacing=pointSpacings(q); %Set desired point spacing
[Fn,Vn]=ggremesh(F,V,optionStructRemesh);

%% Visualisation

cFigure;
gtitle([fileName_FMA,' ',model.preferredName])
subplot(1,2,1);
title('Raw');
gpatch(F,V,'w','r',1,lineWidth);
axisGeom;
camlight headlight;

subplot(1,2,2);
title('Remeshed');
gpatch(Fn,Vn,'w','g',1,lineWidth);
axisGeom;
camlight headlight;
gdrawnow;

%% Saving

modelNew.source=model;
modelNew.faces=Fn;
modelNew.vertices=Vn;
modelNew.pointSpacing=pointSpacings(q);

if saveOn==1
%Create save name with lowercase letters and underscores instead of spaces
saveNameMesh=regexprep(lower(model.preferredName),' ','_');
saveName_mat=fullfile(saveFolder,[saveNameMesh,'.mat']);
save(saveName_mat,'-struct','modelNew')
end

end
97 changes: 97 additions & 0 deletions mcode/C_BodyParts3D_isolateLegOuterSkinSurface.asv
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
clear; close all; clc;

%% Description
% This code processes the MAT file for the skin surface (found in the /mat
% folder), since it contains both the inner and outer skin surfaces. The
% inner surface is removed and the outer surface is processed to produce a
% single "water tight" mesh. The surface is also remeshed using ggremesh.
% The remeshed surface is exported to the /post folder.
%
% This code requires the GIBBON MATLAB toolbox
% <www.gibboncode.org>

%% Plotting settings
lineWidth=0.5;

%% Control parameters

% Path names
projectFolder = fileparts(fileparts(mfilename('fullpath'))); %Main code path
loadFolder=fullfile(projectFolder,'data','BodyParts3D','mat'); %The MAT loading folder
saveFolder=fullfile(projectFolder,'data','BodyParts3D','post'); %The MAT saving folder for processed data

fileName_FMA='FMA7163';
saveNameMesh='skin_leg_right';

pointSpacing=4;
cutHeight=675;
saveOn=1;

%%

fileName_mat=fullfile(loadFolder,[fileName_FMA,'.mat']);

model=load(fileName_mat);
F=model.faces;
V=model.vertices;

%%

logicVertices=V(:,1)<0 & V(:,3)<=cutHeight+mean(patchEdgeLengths(F,V));
logicFaces=any(logicVertices(F),2);
logicFaces=triSurfLogicSharpFix(F,logicFaces);
Fs=F(logicFaces,:);
[Fs,Vs]=patchCleanUnused(Fs,V);

optionStruct.outputType='label';
[G,~,groupSize]=tesgroup(Fs,optionStruct);
[~,indMax]=max(groupSize);
logicKeep=G==indMax;
Fs=Fs(logicKeep,:);
[Fs,Vs]=patchCleanUnused(Fs,Vs);

snapTolerance=mean(patchEdgeLengths(Fs,Vs))/100;
n=vecnormalize([0 0 1]); %Normal direction to plane
P=[0 0 cutHeight]; %Point on plane
[Fc,Vc,~,logicSide]=triSurfSlice(Fs,Vs,[],P,n,snapTolerance);
[Fc,Vc]=patchCleanUnused(Fc(logicSide,:),Vc);

%%

shp = alphaShape(Vc,max(patchEdgeLengths(Fc,Vc)),'HoleThreshold',500,'RegionThreshold',1);
[Fa,Va] = boundaryFacets(shp);
[Fa,Va]=patchCleanUnused(Fa,Va);

optionStruct2.pointSpacing=pointSpacing; %Set desired point spacing
optionStruct2.disp_on=1; % Turn off command window text display
[Fn,Vn]=ggremesh(Fa,Va,optionStruct2);

%% Visualisation

cFigure;
subplot(1,2,1); hold on;
gpatch(F,V,'w','none',0.25);
gpatch(Fn,Vn,'bw','none');
axisGeom;
camlight headlight;

subplot(1,2,2); hold on;
gpatch(Fn,Vn,'bw','k',1,lineWidth);
axisGeom;
camlight headlight;
gdrawnow;

%% Store model in structure

modelNew.source=fileName_FMA;
modelNew.faces=Fn;
modelNew.vertices=Vn;
modelNew.pointSpacing=pointSpacing;
modelNew.cutHeight=cutHeight;

%% Save model

if saveOn==1
saveName_mat=fullfile(saveFolder,[saveNameMesh,'.mat']);
save(saveName_mat,'-struct','modelNew')
end
101 changes: 101 additions & 0 deletions mcode/C_BodyParts3D_isolateLegOuterSkinSurface.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
clear; close all; clc;

%% Description
% This code processes the MAT file for the skin surface (found in the /mat
% folder), since it contains both the inner and outer skin surfaces. The
% inner surface is removed and the outer surface is processed to produce a
% single "water tight" mesh. The surface is also remeshed using ggremesh.
% The remeshed surface is exported to the /post folder.
%
% This code requires the GIBBON MATLAB toolbox
% <www.gibboncode.org>

%% Plotting settings
lineWidth=0.5;

%% Control parameters

% Path names
projectFolder = fileparts(fileparts(mfilename('fullpath'))); %Main code path
loadFolder=fullfile(projectFolder,'data','BodyParts3D','mat'); %The MAT loading folder
saveFolder=fullfile(projectFolder,'data','BodyParts3D','post'); %The MAT saving folder for processed data

fileName_FMA='FMA7163';
saveNameMesh='skin_leg_right';

pointSpacing=4;
cutHeight=675;
saveOn=1;

%%

fileName_mat=fullfile(loadFolder,[fileName_FMA,'.mat']);

model=load(fileName_mat);
F=model.faces;
V=model.vertices;

%%

logicVertices=V(:,1)<0 & V(:,3)<=cutHeight+mean(patchEdgeLengths(F,V));
logicFaces=any(logicVertices(F),2);
logicFaces=triSurfLogicSharpFix(F,logicFaces);
Fs=F(logicFaces,:);
[Fs,Vs]=patchCleanUnused(Fs,V);

optionStruct.outputType='label';
[G,~,groupSize]=tesgroup(Fs,optionStruct);
[~,indMax]=max(groupSize);
logicKeep=G==indMax;
Fs=Fs(logicKeep,:);
[Fs,Vs]=patchCleanUnused(Fs,Vs);

snapTolerance=mean(patchEdgeLengths(Fs,Vs))/100;
n=vecnormalize([0 0 1]); %Normal direction to plane
P=[0 0 cutHeight]; %Point on plane
[Fc,Vc,~,logicSide]=triSurfSlice(Fs,Vs,[],P,n,snapTolerance);
[Fc,Vc]=patchCleanUnused(Fc(logicSide,:),Vc);

%% Construct alpha shape
% This deteriorates surface quality (bridges concave regions) but is a
% termporary "quick-and-dirty" work-around to obtain outer skin surface
% only.

shp = alphaShape(Vc,max(patchEdgeLengths(Fc,Vc)),'HoleThreshold',500,'RegionThreshold',1);
[Fa,Va] = boundaryFacets(shp); %Get boundary faces of alpha shape
[Fa,Va] = patchCleanUnused(Fa,Va); %Remove unused vertices

%% Remesh alpha shape using |ggremesh|
optionStructRemesh.pointSpacing=pointSpacing; %Set desired point spacing
optionStructRemesh.disp_on=1; % Turn off command window text display
[Fn,Vn]=ggremesh(Fa,Va,optionStructRemesh);

%% Visualisation

cFigure;
subplot(1,2,1); hold on;
gpatch(F,V,'w','none',0.25);
gpatch(Fn,Vn,'bw','none');
axisGeom;
camlight headlight;

subplot(1,2,2); hold on;
gpatch(Fn,Vn,'bw','k',1,lineWidth);
axisGeom;
camlight headlight;
gdrawnow;

%% Store model in structure

modelNew.source=fileName_FMA;
modelNew.faces=Fn;
modelNew.vertices=Vn;
modelNew.pointSpacing=pointSpacing;
modelNew.cutHeight=cutHeight;

%% Save model

if saveOn==1
saveName_mat=fullfile(saveFolder,[saveNameMesh,'.mat']);
save(saveName_mat,'-struct','modelNew')
end
Loading

0 comments on commit 033dde5

Please sign in to comment.