Close an open surface in matlab before writing it to an STL-file
8 views (last 30 days)
Show older comments
The below code is generating a bezier surface of a turbine runner blade. The blade is open at the top and bottom an i would like to close it with an other surface before writing it to an STL-file. The reason i want it closed is so that it will be imported as a solid object in Comsol Multiphysics.
I have tried the patch function which fills in the open space but i am not able to get the coordinates for that surface which is needed for the surf2stl function. I have alos tried to do a 2D interpolation using griddata which is partially closing the open surface of the blade.
%function [surf] = surface_gen(x, y, z)
clc;clear all;close all
uCtrl = 3; % Control points in u
wCtrl = 9; % Control points in w
uCell = 50; % Number of cells in u
wCell = 50; % Number of cells in w
% Control points
x = [1.9700 5.3200 9.6400 15.6000 22.9900 16.3800 10.5300 5.9300 1.97;
7.5500 10.4600 13.4600 17.7000 23.5600 18.3300 14.2000 10.9600 7.5500;
19.3900 20.3100 20.7400 21.6200 24.3300 21.9600 21.1600 20.6000 19.3900];
y = [-3.6300 -4.2700 -5.3100 -5.6300 -1.6100 -2.5500 -3.2100 -3.3800 -3.6300;
-7.6800 -6.5300 -6.1900 -5.4800 -0.9800 -2.6700 -4.2400 -5.6600 -7.6800;
-11.2800 -8.3100 -6.3900 -4.4300 0 -2.2700 -4.8400 -7.5700 -11.2800];
z = [-10.2600 -3.7300 1.9500 6.2600 9.0900 6.2600 1.9500 -3.7300 -10.2600;
-20.5000 -14.5500 -8.9300 -4.0500 -0.6000 -4.0500 -8.9300 -14.5500 -20.5000;
-24.9100 -20.7600 -16.5800 -12.4300 -9.0900 -12.4300 -16.5800 -20.7600 -24.9100];
n = uCtrl - 1;
m = wCtrl - 1;
u = linspace(0,1,uCell); % Parametric variable in u
w = linspace(0,1,wCell); % Parametric variable in w
i = 0:n;
j = 0:m;
% Binomial Coefficients
uCoeff = factorial(n)./(factorial(i).*factorial(n-i));
wCoeff = factorial(m)./(factorial(j).*factorial(m-j));
J = NaN(uCtrl,uCell);
K = NaN(wCtrl,wCell);
% Bernstein Basis Functions
for k = 1:uCtrl
J(k,:) = uCoeff(k)*u.^i(k).*(1-u).^(n-i(k));
end
for k = 1:wCtrl
K(k,:) = wCoeff(k)*w.^j(k).*(1-w).^(m-j(k));
end
xPoints = zeros(uCell,wCell);
yPoints = zeros(uCell,wCell);
zPoints = zeros(uCell,wCell);
for i = 1:n+1
for j = 1:m+1
xPoints = J(i,:)'*K(j,:)*x(i,j)+xPoints;
yPoints = J(i,:)'*K(j,:)*y(i,j)+yPoints;
zPoints = J(i,:)'*K(j,:)*z(i,j)+zPoints;
end
end
figure(1)
surf(xPoints,yPoints,zPoints)
xlabel('xPoints')
ylabel('yPoints')
zlabel('zPoints')
% [x_hub,y_hub] = meshgrid(xPoints(1,:),yPoints(1,:));
% z_hub = griddata(xPoints(1,:),yPoints(1,:),zPoints(1,:),x_hub,y_hub);
% [y_shroud,z_shroud] = meshgrid(yPoints(end,:),zPoints(end,:));
% x_shroud = griddata(yPoints(end,:),zPoints(end,:),xPoints(end,:),y_shroud,z_shroud);
% xBlade = zeros(uCell,uCell*3);
% yBlade = zeros(uCell,uCell*3);
% zBlade = zeros(uCell,uCell*3);
% xBlade(:,1:uCell) = xPoints;
% xBlade(:,uCell+1:2*uCell) = x_hub;
% xBlade(:,2*uCell+1:end) = x_shroud;
% yBlade(:,1:uCell) = yPoints;
% yBlade(:,uCell+1:2*uCell) = y_hub;
% yBlade(:,2*uCell+1:end) = y_shroud;
% zBlade(:,1:uCell) = zPoints;
% zBlade(:,uCell+1:2*uCell) = z_hub;
% zBlade(:,2*uCell+1:end) = z_shroud;
% surf(xBlade,yBlade,zBlade)
hold on
plot3(x,y,z,'o','MarkerFaceColor','k')
%surf2stl('blade_closed.stl', xBlade, yBlade, zBlade, 'ascii')
0 Comments
Answers (1)
Maneet Kaur Bagga
on 28 Mar 2024
Hi,
As per my understanding you are generating a turbine blade and want to close the open surface of the top and bottom of the blade preparing it for export to an STL file. Following can be a possible workaround for the same:
Extract the coordinates of the blade surface from the "xPoints", "yPoints" and "zPoints" array, for closing the top and bottom of the surface generate planar caps based on the boundary of these surfaces.
% Top Cap
topCapX = [xPoints(1, :); xPoints(1, :)];
topCapY = [yPoints(1, :); yPoints(1, :)];
topCapZ = [zPoints(1, :); max(zPoints(:)) * ones(size(zPoints(1, :)))];
% Bottom Cap
bottomCapX = [xPoints(end, :); xPoints(end, :)];
bottomCapY = [yPoints(end, :); yPoints(end, :)];
bottomCapZ = [zPoints(end, :); min(zPoints(:)) * ones(size(zPoints(end, :)))];
Combine the original blade surface with the top and bottom caps. Since the aim is to export to an STL file, which is a mesh of triangles, we need to create a triangulated representation of our surfaces. The "surf2patch" function from MATLAB can be used to convert surfaces to patch data.
For using the surf2stl function you can refer to the File Exchange link, or alternatively you can define a custom function as below which performs a Delaunay triangulation, and then export the result to an STL File.
function exportBladeSTL(filename, xPoints, yPoints, zPoints, topCapX, topCapY, topCapZ, bottomCapX, bottomCapY, bottomCapZ)
% Combine all points
X = [xPoints(:); topCapX(:); bottomCapX(:)];
Y = [yPoints(:); topCapY(:); bottomCapY(:)];
Z = [zPoints(:); topCapZ(:); bottomCapZ(:)];
% Create a delaunay triangulation
DT = delaunayTriangulation(X, Y, Z);
% Write to STL
stlwrite(filename, DT.ConnectivityList, DT.Points);
end
Call the function with your data
exportBladeSTL('blade_closed.stl', xPoints, yPoints, zPoints, topCapX, topCapY, topCapZ, bottomCapX, bottomCapY, bottomCapZ);
Please refer to the File Exchange link below to use the "surf2stl" function in MATLAB:
Hope this helps!
0 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!