I use CAD software to generate 3D models, convert those 3D models to an STL format, then load those STL files to Matlab with the following script:
function [points,success] = LoadSTL(path)
% LoadSTL loads an ASCII STL file with units in [mm].
% The output is a structure array where each element in the array is
% a vertex.
%
% [points , success] = LoadSTL(path)
%
% path = String containing the path and extension of the file to be loaded.
% points = Matrix of locations where each column is a vertex, rows are x/y/z/1:
% points(1,:) = x
% points(2,:) = y
% points(3,:) = z
% points(4,:) = 1
% NOTE - every three columns is a new face/facet.
% success = Bit indicating if the file was successfully opened or not.
success = 0;
fileID = fopen(path);
if fileID <0
fprintf('File not found at path %s\n',path);
return;
end
fprintf('Loading Path %s...\n',path);
fileData = fread(fileID,'*char');
eol = sprintf('\n');
stlFile = strsplit(fileData',eol);
fclose(fileID);
fprintf('Done.\n')
pause(0.25);
clc
assignin('base' , 'stlFile' , stlFile)
pointsTracker = 1;
for i=2:size(stlFile,2)
if mod(pointsTracker,100)==0
clc
fprintf('Parsing file at %s...\n',path);
fprintf('Currently logged %d points\n',pointsTracker);
end
testLine = stlFile{i};
rawStrip = strsplit(testLine , ' ' , 'CollapseDelimiters' , true);
if numel(rawStrip) == 5
points(1,pointsTracker) = str2double(rawStrip{1,3})/1000;
points(2,pointsTracker) = str2double(rawStrip{1,4})/1000;
points(3,pointsTracker) = str2double(rawStrip{1,5})/1000;
points(4,pointsTracker) = 1;
pointsTracker = pointsTracker + 1;
end
end
disp('Done.')
pause(0.25);
clc;
if mod(size(points,2),3) > 0
disp('File format in an unexpected type.')
disp('Check the file specified is an STL format file with ASCII formatting.')
disp('(Error - number of vertices not a multiple of 3)')
disp(numel(points.x))
return;
end
success = 1;
return;
Once this is done I save the resulting output (points) as a .mat file and load exclusively from that .mat instead of the STL file because the .mat file loads significantly faster than parsing the STL file every time.
Once you've loaded the file, you can quickly plot the STL file in Matlab with the following command:
myPlotColor = [0.5 0.5 0.5];
nFaces = size(points,2)/3;
patch(...
reshape(points(1,:),3,nFaces) , ...
reshape(points(2,:),3,nFaces) , ...
reshape(points(3,:),3,nFaces) , ...
myPlotColor);
At this point, standard Matlab plot commands work; e.g., axis equal
, hold on
, etc.
Now, given how to load and display STL files in Matlab plots from an m-file, you can go about doing whatever form of control you want. Transform the CAD file with any 4x4 transform matrix composed of a rotation matrix $R$ and translation vector $s$:
$$
\mbox{transformedPoints} = \begin{bmatrix}
& R& & s \\
0 &0 &0& 1 \\
\end{bmatrix}
\mbox{points}
$$
Plot the transformed points with the patch
command shown above. As long as you've generated your CAD model such that the origin of your 3D model corresponds with the origin of your mathematical model then any movement/rotation of the mathematical model about its origin can be correctly applied to the CAD model, which can then be displayed.
I'd just like to reiterate that this file loads STL files that are in ASCII format with units in millimeters, and the resulting plot is with units in meters, but of course you can change that with the /1000
scaling during the loading of the file.