how I can find points on a 3D polygon that are separated with specific distance

1 view (last 30 days)
Dear Matlab experts,
I am working on a project to make a 3D mask for patients using 3D printer. these masks should have groves with certain diameter along the mask which should be separated with specific distance from each other to place wires in them. I managed to convert the patient's head contour which obtained as a series of 3 columns arrays (X,Y,Z) to a voxelised images and then to a 3D mesh then export it as an STL file. However, I am still straggling of making these groves on the top of the 3D mesh. Could anyone help me with that. Then is my code:
% import the body contours from the dicom patient structure file.
RTS=dicominfo('RTSTRUCT.dcm');
% select the regio of interest (ROI) numberfor process
ROI=21;
% find the total number of contours in this ROI.
eval(['N_R=sum(structfun(@numel,RTS.ROIContourSequence.Item_' num2str(ROI) '.ContourSequence));']);
%find the X,Y,Z location for each contour
R=cell(N_R,1);
R1=cell(N_R,1);
R2=cell(N_R,1);
for i=1:N_R
eval(['R{' num2str(i) '}=RTS.ROIContourSequence.Item_' num2str(ROI) '.ContourSequence.Item_' num2str(i) '.ContourData;']);
R1{i}=reshape(R{i},3,length(R{i})/3);
R1{i}=R1{i}';
end
% extend the each contour by 5 and 10 mm using
%extendPloy (from file exchange)
for i=1:N_R
waitbar(i/N_R)
R2{i}=[R1a{i}(:,1),R1a{i}(:,2)];
R3{i}=extendPoly(R2{i},5,pi/50);
R4{i}=extendPoly(R2{i},10,pi/50);
end
% define the x and y location in the dicom image where the ROI contour was
% drawn usually the dicom image are 512x512 so x and y that are the same.
x=-250:0.977:250;
x=x';
bx1=cell(N_R,1);
by1=cell(N_R,1);
bx2=cell(N_R,1);
by2=cell(N_R,1);
bx3=cell(N_R,1);
by3=cell(N_R,1);
% find the corsponding pixel for each expanded contour in the dicom image.
for j=1:N_R
for i=1:length(R2{j}(:,1))
tmp=abs(x-R2{j}(i,1));
[a, bx1{j}(i)]=min(tmp);
tmp2=abs(x-R2{j}(i,2));
[a, by1{j}(i)]=min(tmp2);
end
for i=1:length(R3{j}{1}(:,1))
tmp=abs(x-R3{j}{1}(i,1));
[a, bx2{j}(i)]=min(tmp);
tmp2=abs(x-R3{j}{1}(i,2));
[a, by2{j}(i)]=min(tmp2);
end
for i=1:length(R4{j}{1}(:,1))
tmp=abs(x-R4{j}{1}(i,1));
[a bx3{j}(i)]=min(tmp);
tmp2=abs(x-R4{j}{1}(i,2));
[a by3{j}(i)]=min(tmp2);
end
end
% find the boolean mask for origenal and extended contours.
Msk0=cell(N_R,1);
Msk1=cell(N_R,1);
Msk2=cell(N_R,1);
for i=1:N_R
Msk0{i}=poly2mask(bx1{i},by1{i},512,512);
Msk0a{i}=Msk0{i};
Msk1{i}=poly2mask(bx2{i},by2{i},512,512);
Msk1a{i}=Msk1{i};
Msk2{i}=poly2mask(bx3{i},by3{i},512,512);
Msk2a{i}=Msk2{i};
end
% define circle points.
circlP=0:0.01:2*pi+0.01;
xs=cell(N_R,1);
ys=cell(N_R,1);
xx=1:512;
xx=xx';
% set the first point
P0=R3{1}{1}(1,:);
% find starting point in all contours
P00=cell(N_R,1);
bp0{i}=cell(N_R,1);
for i=1:N_R
tt=abs(R3{i}{1}(:,1)-P0(1,1));
[a, bp0{i}]=min(tt);
P00{i}(1,:)=R3{i}{1}(bp0{i},:);
end
% rearrage the arrays to start from P00
R3b=cell(N_R,1);
for i=1:N_R
n=length(R3{i}{1});
p1=n-bp0{i};
R3b{i}(1:p1+1,:)=R3{i}{1}(bp0{i}:n,:);
R3b{i}(p1+2:n,:)=R3{i}(1:bp0{i}-1,:);
R3{i}{1}=R3b{i};
end
% find the distance between P00 and all point in the contour
r=cell(N_R,1);
m=cell(N_R,1);
for j=1:N_R
mm=0;
for i=1:length(R3{j}{1}(:,1))-1
m{j}(i)=((R3{j}{1}(i+1,1)-R3{j}{1}(i,1))^2+(R3{j}{1}(i+1,2)-R3{j}{1}(i,2))^2)^0.5;
mm=mm+m{j}(i);
r{j}(i)=mm;
end
end
%number of wire
N_w=5;
%wire dimeter in mm
w_d=3;
% wires' separation in mm
w_s=20;
%find the corresponding points in each contour
P=cell(N_R,1);
xp=cell(N_R,1);
yp=cell(N_R,1);
nxp=cell(N_R,1);
nyp=cell(N_R,1);
for j=1:N_R
for i=1:N_w+1
tt=abs(r{j}-w_s*(i-1));
[a, P{j}(i)]=min(tt);
end
xp{j}=R3{j}{1}(P{j},1);
yp{j}=R3{j}{1}(P{j},2);
end
% find the position of these points in the dicom image
for j=1:N_R
for i=1:N_w+1
tmp=abs(x-xp{j}(i));
[a, nxp{j}(i)]=min(tmp);
tmp2=abs(x-yp{j}(i));
[a, nyp{j}(i)]=min(tmp2);
end
end
% find all points in the circle with w_d diameter and (nxp,nyp) centre.
xs=cell(N_R,1);
ys=cell(N_R,1);
for j=1:N_R
for i=1:N_w+1
xs{j}{i}=((w_d/2)*sin(circlP)+nxp{j}(i));
ys{j}{i}=((w_d/2)*cos(circlP)+nyp{j}(i));
end
end
% set all points in the mask and inside the circle to 0
for j=1:N_R
for i=1:N_w+1
for k=1:length(xs{j}{i})
Msk1a{j}(round(ys{j}{i}),round(xs{j}{i}))=0;
Msk2a{j}(round(ys{j}{i}),round(xs{j}{i}))=0;
end
end
end
% find the mask inner and outer layers
Msk0b=cell(N_R,1);
Msk1b=cell(N_R,1);
Msk3=cell(N_R,1);
Msk4=cell(N_R,1);
for i=1:N_R
Msk0b{i}=~Msk0{i};
Msk1b{i}=~Msk1{i};
Msk3{i}=Msk1a{i}.*Msk0b{i};
Msk4{i}=Msk2a{i}.*Msk1b{i};
end
Msk_3d1=zeros(512,512,N_R);
Msk_3d2=zeros(512,512,N_R);
for i=1:N_R
Msk_3d1(:,:,i)=Msk3{i};
Msk_3d2(:,:,i)=Msk4{i};
end
% set the equivalent z location of the 3d masks which was obtain from
% the slice thickness of the CT dicom images.
z=0:0.625:(0.625*(N_R-1));
z=z';
% smooth the 3D masks
Ds1=smooth3(Msk_3d1,'gaussian');
Ds2=smooth3(Msk_3d2,'gaussian');
% create the STL file of the inner and outer masks using
% CONVERT_voxels_to_stl (from file exchage).
[filename, folder]=uiputfile('*.stl','Select file to save the inner mask file As');
fullname=fullfile(folder,filename);
CONVERT_voxels_to_stl(fullname,Ds1,x,x,z);
[filename, folder]=uiputfile('*.stl','Select file to save the outer mask file As');
fullname=fullfile(folder,filename);
CONVERT_voxels_to_stl(fullname,Ds2,x,x,z);
% end of code

Answers (0)

Categories

Find more on Read, Write, and Modify Image in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!