close all
clear
clc
dimensionX = 10;
dimensionY = 10;
dimensionZ = 10;
resolution = 0.5;
cellLength = 10;
thickness = 1;
FV=createGyroid(dimensionX,dimensionY,dimensionZ,resolution,cellLength,thickness);
f = @(x, y, z) z - 3;
createIntersectedVolume(dimensionX,dimensionY,dimensionZ,resolution,cellLength,thickness,f,FV);
f = @(x, y, z) x.*x + y.*y -25;
createIntersectedVolume(dimensionX,dimensionY,dimensionZ,resolution,cellLength,thickness,f,FV);
function createIntersectedVolume(dimensionX,dimensionY,dimensionZ,resolution,cellLength,thickness,f,FV)
xv = FV.vertices(:, 1);
yv = FV.vertices(:, 2);
zv = FV.vertices(:, 3);
fv=f(xv,yv,zv);
removePoints = find(fv > 0);
keepPoints = find(fv <= 0);
insideV.faces = FV.faces;
insideV.vertices = FV.vertices;
outsideV.faces = FV.faces;
outsideV.vertices = FV.vertices;
frontierV.faces = FV.faces;
frontierV.vertices= FV.vertices;
j=1;
for i = size(FV.faces,1):-1:1
inpt1=find(FV.faces(i,1)==keepPoints);
inpt2=find(FV.faces(i,2)==keepPoints);
inpt3=find(FV.faces(i,3)==keepPoints);
if (isempty(inpt1) && isempty(inpt2) && isempty(inpt3))
FV.faces(i,:)=[];
insideV.faces(i,:)=[];
frontierV.faces(i,:)=[];
elseif ~(isempty(inpt1) || isempty(inpt2) || isempty(inpt3))
outsideV.faces(i,:)=[];
frontierV.faces(i,:)=[];
else
insideV.faces(i,:)=[];
outsideV.faces(i,:)=[];
end
end
for i = size(FV.faces,1):-1:1
ptin=[];
ptout=[];
for j=1:3
inptj=find(FV.faces(i,j)==keepPoints);
if ~isempty(inptj)
ptin=[ptin FV.faces(i,j)];
else
ptout=[ptout FV.faces(i,j)];
end
end
tolerance = 10e-2;
if size(ptout,2)==1
if i==1108
disp('');
end
[xNew, yNew, zNew] = fintersect(FV.vertices(ptin(1),1),FV.vertices(ptin(1),2),FV.vertices(ptin(1),3),...
FV.vertices(ptout,1), FV.vertices(ptout,2), FV.vertices(ptout,3),f);
newCoords=[xNew,yNew,zNew];
existingIndex = findExistingVertex(FV.vertices, newCoords, tolerance);
if ~isempty(existingIndex)
FV.faces(FV.faces == ptout) = existingIndex;
ptId=existingIndex;
else
FV.vertices(ptout, [1,2,3]) = newCoords;
ptId=ptout;
end
ind=size(FV.vertices,1)+1;
[FV.vertices(ind,1), FV.vertices(ind,2), FV.vertices(ind,3)] = ...
fintersect(FV.vertices(ptin(2),1),FV.vertices(ptin(2),2),FV.vertices(ptin(2),3),...
FV.vertices(ptout,1), FV.vertices(ptout,2), FV.vertices(ptout,3),f);
newVertex=[FV.vertices(ind,1), FV.vertices(ind,2), FV.vertices(ind,3)];
existingIndex = findExistingVertex(FV.vertices, newVertex, tolerance);
if isempty(existingIndex)
FV.faces(end+1,1:3)=[ptin(2) ptId ind];
else
ind=existingIndex;
FV.faces(end+1,1:3)=[ptin(2) ptId ind];
end
elseif size(ptout,2)==2
for j=1:2
[xNew, yNew, zNew] = fintersect(FV.vertices(ptin,1),FV.vertices(ptin,2),FV.vertices(ptin,3),...
FV.vertices(ptout(j),1), FV.vertices(ptout(j),2), FV.vertices(ptout(j),3),f);
newCoords=[xNew,yNew,zNew];
existingIndex = findExistingVertex(FV.vertices, newCoords, tolerance);
if ~isempty(existingIndex)
FV.faces(FV.faces == ptout(j)) = existingIndex;
else
FV.vertices(ptout(j), :) = newCoords;
end
end
elseif ~isempty(ptout)
erreur('cas non prévu');
end
end
if any(FV.faces(:) > size(FV.vertices, 1))
error('Some indices in FV.faces exceed the size of FV.vertices');
end
Vertices_to_keep=false(size(FV.vertices,1),1);
for ii=1:size(FV.faces,1)
Vertices_to_keep(FV.faces(ii,:))=true;
end
FV.vertices=FV.vertices(Vertices_to_keep,:);
mapOld_toNew=zeros(size(Vertices_to_keep,1));
mapOld_toNew(Vertices_to_keep)=1:sum(Vertices_to_keep);
for ii=1:size(FV.faces,1)
FV.faces(ii,:)=mapOld_toNew(FV.faces(ii,:));
end
figure;
plotStructure(FV);
plotf(dimensionX,dimensionY,dimensionZ,resolution,cellLength,thickness,f)
end
function FV=createGyroid(dimensionX,dimensionY,dimensionZ,resolution,cellLength,thickness)
x = linspace(-dimensionX/2, dimensionX/2, dimensionX/resolution);
y = linspace(-dimensionY/2, dimensionY/2, dimensionY/resolution);
z = linspace(-dimensionZ/2, dimensionZ/2, dimensionZ/resolution);
[X, Y, Z] = meshgrid(x, y, z);
F1 = cos(2*pi*X/cellLength).*sin(2*pi*Y/cellLength) + ...
cos(2*pi*Y/cellLength).*sin(2*pi*Z/cellLength) + ...
cos(2*pi*Z/cellLength).*sin(2*pi*X/cellLength) + ...
thickness/2;
F2 = cos(2*pi*X/cellLength).*sin(2*pi*Y/cellLength) + ...
cos(2*pi*Y/cellLength).*sin(2*pi*Z/cellLength) + ...
cos(2*pi*Z/cellLength).*sin(2*pi*X/cellLength) - ...
thickness/2;
F3 = F1.*F2;
FV = isosurface(X, Y, Z, F3, 0);
end
function plotf(dimensionX,dimensionY,dimensionZ,resolution,cellLength,thickness,f)
x = linspace(-dimensionX/2, dimensionX/2, dimensionX/resolution);
y = linspace(-dimensionY/2, dimensionY/2, dimensionY/resolution);
z = linspace(-dimensionZ/2, dimensionZ/2, dimensionZ/resolution);
[X, Y, Z] = meshgrid(x, y, z);
F = f(X, Y, Z);
hold on;
p1 = patch(isosurface(X, Y, Z, F, 0));
p1.FaceColor = 'blue';
p1.EdgeColor = 'none';
p1.FaceAlpha = 0.2;
hold off;
end
function plotStructure(FV)
pFV = patch(FV);
face_colors = rand(size(FV.faces, 1), 3);
set(pFV, 'FaceVertexCData', face_colors, 'FaceColor', 'flat', 'EdgeColor', 'none');
hold off;
daspect([1 1 1])
view([120, 15])
camlight
lighting flat
xlabel('X')
ylabel('Y')
zlabel('Z')
end
function [x, y, z] = fintersect(x1, y1, z1, x2, y2, z2, f)
xt = @(t) x1 + t * (x2 - x1);
yt = @(t) y1 + t * (y2 - y1);
zt = @(t) z1 + t * (z2 - z1);
tsurface = @(t) f(xt(t), yt(t), zt(t));
tsol = fzero(tsurface, 0.5);
x = xt(tsol);
y = yt(tsol);
z = zt(tsol);
end
function index = findExistingVertex(vertices, newVertex, tolerance)
diffs = vecnorm(vertices - newVertex, 2, 2);
index = find(diffs < tolerance, 1);
end