stl_write

PURPOSE ^

STL_WRITE Create an STL file from a patch struct

SYNOPSIS ^

function stl_write(fv, name, type)

DESCRIPTION ^

STL_WRITE Create an STL file from a patch struct

 STL_WRITE(mdl, name) where:
  mdl is an eidors fwd_model structure. 
  name is the file name (character string), if no extension given, 'stl'
  assumed.
  STL_WRITE will use mdl.elems if they are triangles. Otherwise, it will
  use mdl.boundary or, if absent, call find_boundary.

 STL_WRITE(fv, name) where:
  fv is face-vertex (patch) structure (fv.faces, fv.vertices)
  name is the file name (character string), if no extension given, 'stl'
  assumed.

 STL_WRITE(fv, name, type) specifies the type of file to write:
  'bin'  - binary file (default)
  'txt'  - ASCII file

 See also: STL_READ, FIND_BOUNDARY

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function stl_write(fv, name, type)
0002 %STL_WRITE Create an STL file from a patch struct
0003 %
0004 % STL_WRITE(mdl, name) where:
0005 %  mdl is an eidors fwd_model structure.
0006 %  name is the file name (character string), if no extension given, 'stl'
0007 %  assumed.
0008 %  STL_WRITE will use mdl.elems if they are triangles. Otherwise, it will
0009 %  use mdl.boundary or, if absent, call find_boundary.
0010 %
0011 % STL_WRITE(fv, name) where:
0012 %  fv is face-vertex (patch) structure (fv.faces, fv.vertices)
0013 %  name is the file name (character string), if no extension given, 'stl'
0014 %  assumed.
0015 %
0016 % STL_WRITE(fv, name, type) specifies the type of file to write:
0017 %  'bin'  - binary file (default)
0018 %  'txt'  - ASCII file
0019 %
0020 % See also: STL_READ, FIND_BOUNDARY
0021 
0022 % (C) 2006 Eric Carlson: Public Domain
0023 % Adapted by Bartlomiej Grychtol from:
0024 % http://www.mathworks.com/matlabcentral/newsreader/view_thread/126215
0025 % $Id: stl_write.m 6836 2024-05-02 08:24:41Z bgrychtol $
0026 
0027 
0028 [folder, label, ext] = fileparts(name);
0029 if isempty(ext), ext = '.stl'; end
0030 if isempty(folder)
0031    name = [label ext];
0032 else
0033    name = [folder filesep label ext];
0034 end
0035 
0036 if isfield(fv, 'type') && strcmp(fv.type, 'fwd_model')
0037    fv.vertices = fv.nodes;
0038    if size(fv.elems,2)== 3
0039        fv.faces = fv.elems;
0040    else
0041        try
0042            fv.faces = fv.boundary;
0043        catch
0044            fv.faces = find_boundary(fv);
0045        end
0046    end
0047 end
0048 fv.vertices = double(fv.vertices);
0049 v1 = fv.vertices(fv.faces(:,2),:)-fv.vertices(fv.faces(:,1),:);
0050 v2 = fv.vertices(fv.faces(:,3),:)-fv.vertices(fv.faces(:,2),:);
0051 Norms = cross3(v1,v2);
0052 clear v1 v2
0053 fv.vertices = single(fv.vertices);
0054 v1(:,1:3) = fv.vertices(fv.faces(:,1),1:3);
0055 v2(:,1:3) = fv.vertices(fv.faces(:,2),1:3);
0056 v3(:,1:3) = fv.vertices(fv.faces(:,3),1:3);
0057 
0058 if nargin < 3 
0059     type = 'bin';
0060 end
0061 switch type
0062     case 'bin'
0063         write_bin_stl(name, label, Norms, v1, v2, v3);
0064     case 'txt' 
0065         write_txt_stl(name, label, Norms, v1, v2, v3);
0066     otherwise
0067         error('EIDORS:WrongInput','Type can only be ''bin'' or ''txt''');
0068 end
0069 
0070 
0071 function write_bin_stl(name, label, Norms, v1, v2, v3)
0072 progress_msg('Writing binary STL file...')
0073 fid = fopen(name,'wb','ieee-le');
0074 header = label;
0075 if length(header) > 80
0076     header = header(1:80);
0077 else
0078     header(end+1:80) = '-';
0079 end
0080 fwrite(fid, header, 'char');
0081 nf = size(v1,1);
0082 fwrite(fid, uint32(nf), 'uint32');
0083 for k = 1:nf
0084     if mod(k,100)==0, progress_msg(k/nf); end
0085     fwrite(fid, [Norms(k,:), v1(k,:), v2(k,:), v3(k,:)], 'float32');
0086     fwrite(fid, 0,'uint16');
0087 end
0088 fclose(fid);
0089 progress_msg(Inf)
0090 
0091 
0092 function write_txt_stl(name, label, Norms, v1, v2, v3)
0093 progress_msg('Writing ASCII STL file...')
0094 fid = fopen(name,'w');
0095 fprintf(fid,'solid %s\n',label);
0096 nf = size(v1,1);
0097 for k = 1:nf
0098     if mod(k,100)==0, progress_msg(k/nf); end
0099     fprintf(fid,['facet normal %.12g %.12g %.12g\n' ... 
0100                  '\t' 'outer loop\n' ... 
0101                  '\t\t' 'vertex %.12g %.12g %.12g\n' ...
0102                  '\t\t' 'vertex %.12g %.12g %.12g\n' ...
0103                  '\t\t' 'vertex %.12g %.12g %.12g\n' ...
0104                  '\t' 'endloop\n' ...
0105                  'endfacet\n'], ...
0106         Norms(k,1),Norms(k,2),Norms(k,3), ...
0107         v1(k,1), v1(k,2), v1(k,3), ...
0108         v2(k,1), v2(k,2), v2(k,3), ...
0109         v3(k,1), v3(k,2), v3(k,3) );
0110 end
0111 fprintf(fid,'endsolid %s\n',label);
0112 fclose(fid);
0113 progress_msg(Inf)
0114 
0115 function M=cross3(r,F)
0116 % function to calculate normalized cross product rxF/|rxF|
0117 % handles (same-size) arrays (n by 3) for r and F
0118 %
0119        M = [(r(:,2).*F(:,3) - r(:,3).*F(:,2)) ...
0120             (r(:,3).*F(:,1) - r(:,1).*F(:,3)) ...
0121             (r(:,1).*F(:,2) - r(:,2).*F(:,1))];
0122        M_mag = sqrt(sum((M.*M)')');
0123        M(:,1) = M(:,1)./M_mag;
0124        M(:,2) = M(:,2)./M_mag;
0125        M(:,3) = M(:,3)./M_mag;

Generated on Sun 29-Dec-2024 11:41:59 by m2html © 2005