1

Good day, I would like to seek for helps on how to convert the 3D Coordinates (x,y,z) into .STL file in MATLAB.

Below are some of the 3D Coordinates I simulated and obtained in MATLAB and stored it in a .txt file.

P =

14  0   25
16  0   20
15  4   24
10  3   6
7   5   37
5   7   3
7   0   37
3   1   37
5   1   4
...
(many more)

Note that the first column contains the x coordinates, second column contains the y coordinates and the third column contains the z coordinates.

I explored the methods below:

tri = delaunayTriangulation(P)
tetramesh(tri)

and I get the 3D Object as below:

3D Object

and also

TR = delaunay(P(:,1), P(:,2);
output = trimesh(TR,P(:,1),P(:,2),P(:,3));

Another 3D Object View

For both, I tried to use stlwrite() function to export it into .stl file, but unfortunately, I failed all the times.

Failed 1: tetramesh

DT = delaunayTriangulation(x,y,z);
tetramesh(DT);

Error Message:

Error using stlwrite (line 33)
Tetrahedron triangulation is not supported.

Error in Wong_STL (line 173)
stlwrite(DT,'FinalOutputTrimesh.stl')

Failed 2: trimesh

DT = delaunay(x,y,z);
trimesh(DT,x,y,z);

Error Message:

Error using stlwrite (line 25)
Input argument must be a triangulation object.

Error in Wong_STL (line 161)
stlwrite(DT,'FinalOutputTrimesh.stl')

Now, I am trying to solve as below, but I have no idea how to find T.

P = (x,y,z)
T = ??? ??? ???
TR = triangulation(T, P);
stlwrite(TR,'tritext.stl','text')

I need to know how to find T, so that I am able to export the 3D coordinates to STL file.

Could someone share his/her knowledge on how to solve this 3D Coordinates converting into .stl file problem?

Jay
  • 11
  • 5
  • We can't really help you without knowing how you called `stlwrite` and how your attempts failed. Please update your question. – beaker Aug 07 '20 at 15:05
  • @beaker I have updated the errors I found above. Could you help figure it out? Thousand thanks from me. – Jay Aug 07 '20 at 16:53

1 Answers1

0

Perhaps you could use this function found on the Matlab Stack Exchange. I've used it previously. It takes data stored in three values: X, Y, Z, where X corresponds to the columns of Z and Y corresponds to the rows. It then uses scalar values of dx and dy to specify the x and y spacing between grid points to map the file.

Hope this helps. Sorry I don't have a more detailed explanation, as I found this function from one of my colleagues.

    nfacets = 0;
    
    for i=1:(size(z,1)-1)
        for j=1:(size(z,2)-1)
            
            p1 = [x(i,j)     y(i,j)     z(i,j)];
            p2 = [x(i,j+1)   y(i,j+1)   z(i,j+1)];
            p3 = [x(i+1,j+1) y(i+1,j+1) z(i+1,j+1)];
            val = local_write_facet(fid,p1,p2,p3,mode);
            nfacets = nfacets + val;
            
            p1 = [x(i+1,j+1) y(i+1,j+1) z(i+1,j+1)];
            p2 = [x(i+1,j)   y(i+1,j)   z(i+1,j)];
            p3 = [x(i,j)     y(i,j)     z(i,j)];        
            val = local_write_facet(fid,p1,p2,p3,mode);
            nfacets = nfacets + val;
            
        end
    end
    
    if strcmp(mode,'ascii')
        fprintf(fid,'endsolid %s\r\n',title_str);
    else
        fseek(fid,0,'bof');
        fseek(fid,80,'bof');
        fwrite(fid,nfacets,'int32');
    end
    
    fclose(fid);
    
    disp( sprintf('Wrote %d facets',nfacets) );

% Local subfunctions

function num = local_write_facet(fid,p1,p2,p3,mode)

if any( isnan(p1) | isnan(p2) | isnan(p3) )
    num = 0;
    return;
else
    num = 1;
    n = local_find_normal(p1,p2,p3);
    
    if strcmp(mode,'ascii')
        
        fprintf(fid,'facet normal %.7E %.7E %.7E\r\n', n(1),n(2),n(3) );
        fprintf(fid,'outer loop\r\n');        
        fprintf(fid,'vertex %.7E %.7E %.7E\r\n', p1);
        fprintf(fid,'vertex %.7E %.7E %.7E\r\n', p2);
        fprintf(fid,'vertex %.7E %.7E %.7E\r\n', p3);
        fprintf(fid,'endloop\r\n');
        fprintf(fid,'endfacet\r\n');
        
    else
        
        fwrite(fid,n,'float32');
        fwrite(fid,p1,'float32');
        fwrite(fid,p2,'float32');
        fwrite(fid,p3,'float32');
        fwrite(fid,0,'int16');  % unused
        
    end
    
end


function n = local_find_normal(p1,p2,p3)

v1 = p2-p1;
v2 = p3-p1;
v3 = cross(v1,v2);
n = v3 ./ sqrt(sum(v3.*v3));
Laurel Link
  • 195
  • 1
  • 4
  • 15