forked from maximm8/VisualHull
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpatch2stl.m
121 lines (95 loc) · 2.93 KB
/
patch2stl.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
function patch2stl(filename,p,mode)
%PATCH2STL Write STL file from patch (vertices/faces) data.
% PATCH2STL('filename',p) writes a stereolithography (STL) file
% for a patch mesh defined by P. P must be a structure with 'VERTICES'
% and 'FACES' fields.
%
% PATCH2STL(...,'mode') may be used to specify the output format.
%
% 'binary' - writes in STL binary format (default)
% 'ascii' - writes in STL ASCII format
%
% Example:
%
% tmpvol = zeros(20,20,20); % Empty voxel volume
% tmpvol(8:12,8:12,5:15) = 1; % Turn some voxels on
% fv = isosurface(tmpvol, 0.99); % Create the patch object
% patch2stl('test.stl',fv) % Save to binary .stl
% Based on surf2stl by Bill McDonald
%
% Author: Sven Holcombe, 07-30-08
error(nargchk(2,3,nargin));
if (ischar(filename)==0)
error( 'Invalid filename');
end
if (nargin < 3)
mode = 'binary';
elseif (strcmp(mode,'ascii')==0)
mode = 'binary';
end
if (~(isfield(p,'vertices') && isfield(p,'faces')))
error( 'Variable p must be a faces/vertices structure' );
end
if strcmp(mode,'ascii')
% Open for writing in ascii mode
fid = fopen(filename,'w');
else
% Open for writing in binary mode
fid = fopen(filename,'wb+');
end
if (fid == -1)
error('patch2stl:cannotWriteFile', 'Unable to write to %s', filename);
end
title_str = sprintf('Created by patch2stl.m %s',datestr(now));
if strcmp(mode,'ascii')
fprintf(fid,'solid %s\r\n',title_str);
else
str = sprintf('%-80s',title_str);
fwrite(fid,str,'uchar'); % Title
fwrite(fid,0,'int32'); % Number of facets, zero for now
end
nfacets = 0;
% Main loop
for i=1:length(p.faces)
p123 = p.vertices(p.faces(i,:),:);
val = local_write_facet(fid,p123(1,:),p123(2,:),p123(3,:),mode);
nfacets = nfacets + val;
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));