-
Notifications
You must be signed in to change notification settings - Fork 6
/
VTKwrite.m
270 lines (262 loc) · 11.4 KB
/
VTKwrite.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
function vtkwrite( filename,dataType,varargin )
% VTKWRITE Writes 3D Matlab array into VTK file format.
% vtkwrite(filename,'structured_grid',x,y,z,'vectors',title,u,v,w) writes
% a structured 3D vector data into VTK file, with name specified by the string
% filename. (u,v,w) are the vector components at the points (x,y,z). x,y,z
% should be 3-D matrices like those generated by meshgrid, where
% point(ijk) is specified by x(i,j,k), y(i,j,k) and z(i,j,k).
% The matrices x,y,z,u,v,w must all be the same size and contain
% corrresponding position and vector component. The string title specifies
% the name of the vector field to be saved.
%
% vtkwrite(filename,'structured_grid',x,y,z,'scalars',title,r) writes a 3D
% scalar data into VTK file whose name is specified by the string
% filename. r is the scalar value at the points (x,y,z). The matrices
% x,y,z,r must all be the same size and contain the corresponding position
% and scalar values.
%
% vtkwrite(filename,'structured_grid',x,y,z,'vectors',title,u,v,w,'scalars',
% title2,r) writes a 3D structured grid that contains both vector and scalar values.
% x,y,z,u,v,w,r must all be the same size and contain the corresponding
% positon, vector and scalar values.
%
% vtkwrite(filename, 'structured_points', title, m) saves matrix m (could
% be 1D, 2D or 3D array) into vtk as structured points.
%
% vtkwrite(filename, 'structured_points', title, m, 'spacing', sx, sy, sz)
% allows user to specify spacing. (default: 1, 1, 1). This is the aspect
% ratio of a single voxel.
%
% vtkwrite(filename, 'structured_points', title, m, 'origin', ox, oy, oz)
% allows user to speicify origin of dataset. (default: 0, 0, 0).
%
% vtkwrite(filename,'unstructured_grid',x,y,z,'vectors',title,u,v,w,'scalars',
% title2,r) writes a 3D unstructured grid that contains both vector and scalar values.
% x,y,z,u,v,w,r must all be the same size and contain the corresponding
% positon, vector and scalar values.
%
% vtkwrite(filename, 'polydata', 'lines', x, y, z) exports a 3D line where
% x,y,z are coordinates of the points that make the line. x, y, z are
% vectors containing the coordinates of points of the line, where point(n)
% is specified by x(n), y(n) and z(n).
%
% vtkwrite(filename,'polydata','lines',x,y,z,'Precision',n) allows you to
% specify precision of the exported number up to n digits after decimal
% point. Default precision is 3 digits.
%
% vtkwrite(filename,'polydata','triangle',x,y,z,tri) exports a list of
% triangles where x,y,z are the coordinates of the points and tri is an
% m*3 matrix whose rows denote the points of the individual triangles.
%
% vtkwrite(filename,'polydata','tetrahedron',x,y,z,tetra) exports a list
% of tetrahedrons where x,y,z are the coordinates of the points
% and tetra is an m*4 matrix whose rows denote the points of individual
% tetrahedrons.
%
% vtkwrite('execute','polydata','lines',x,y,z) will save data with default
% filename ''matlab_export.vtk' and automatically loads data into
% ParaView.
%
% Version 2.3
% Copyright, Chaoyuan Yeh, 2016
% Codes are modified from William Thielicke and David Gingras's submission.
if strcmpi(filename,'execute'), filename = 'matlab_export.vtk'; end
fid = fopen(filename, 'w');
% VTK files contain five major parts
% 1. VTK DataFile Version
fprintf(fid, '# vtk DataFile Version 2.0\n');
% 2. Title
fprintf(fid, 'VTK from Matlab\n');
binaryflag = any(strcmpi(varargin, 'BINARY'));
if any(strcmpi(varargin, 'PRECISION'))
precision = num2str(varargin{find(strcmpi(vin, 'PRECISION'))+1});
else
precision = '2';
end
switch upper(dataType)
case 'STRUCTURED_POINTS'
title = varargin{1};
m = varargin{2};
if any(strcmpi(varargin, 'spacing'))
sx = varargin{find(strcmpi(varargin, 'spacing'))+1};
sy = varargin{find(strcmpi(varargin, 'spacing'))+2};
sz = varargin{find(strcmpi(varargin, 'spacing'))+3};
else
sx = 1;
sy = 1;
sz = 1;
end
if any(strcmpi(varargin, 'origin'))
ox = varargin{find(strcmpi(varargin, 'origin'))+1};
oy = varargin{find(strcmpi(varargin, 'origin'))+2};
oz = varargin{find(strcmpi(varargin, 'origin'))+3};
else
ox = 0;
oy = 0;
oz = 0;
end
[nx, ny, nz] = size(m);
setdataformat(fid, binaryflag);
fprintf(fid, 'DATASET STRUCTURED_POINTS\n');
fprintf(fid, 'DIMENSIONS %d %d %d\n', nx, ny, nz);
fprintf(fid, ['SPACING ', num2str(sx), ' ', num2str(sy), ' ',...
num2str(sz), '\n']);
fprintf(fid, ['ORIGIN ', num2str(ox), ' ', num2str(oy), ' ',...
num2str(oz), '\n']);
fprintf(fid, 'POINT_DATA %d\n', nx*ny*nz);
fprintf(fid, ['SCALARS ', title, ' float 1\n']);
fprintf(fid,'LOOKUP_TABLE default\n');
if ~binaryflag
spec = ['%0.', precision, 'f '];
fprintf(fid, spec, m(:)');
else
fwrite(fid, m(:)', 'float', 'b');
end
case {'STRUCTURED_GRID','UNSTRUCTURED_GRID'}
% 3. The format data proper is saved in (ASCII or Binary). Use
% fprintf to write data in the case of ASCII and fwrite for binary.
if numel(varargin)<6, error('Not enough input arguments'); end
setdataformat(fid, binaryflag);
% fprintf(fid, 'BINARY\n');
x = varargin{1};
y = varargin{2};
z = varargin{3};
if sum(size(x)==size(y) & size(y)==size(z))~=length(size(x))
error('Input dimesions do not match')
end
n_elements = numel(x);
% 4. Type of Dataset ( can be STRUCTURED_POINTS, STRUCTURED_GRID,
% UNSTRUCTURED_GRID, POLYDATA, RECTILINEAR_GRID or FIELD )
% This part, dataset structure, begins with a line containing the
% keyword 'DATASET' followed by a keyword describing the type of dataset.
% Then the geomettry part describes geometry and topology of the dataset.
if strcmpi(dataType,'STRUCTURED_GRID')
fprintf(fid, 'DATASET STRUCTURED_GRID\n');
fprintf(fid, 'DIMENSIONS %d %d %d\n', size(x,1), size(x,2), size(x,3));
else
fprintf(fid, 'DATASET UNSTRUCTURED_GRID\n');
end
fprintf(fid, ['POINTS ' num2str(n_elements) ' float\n']);
output = [x(:)'; y(:)'; z(:)'];
if ~binaryflag
spec = ['%0.', precision, 'f '];
fprintf(fid, spec, output);
else
fwrite(fid, output, 'float', 'b');
end
% 5.This final part describe the dataset attributes and begins with the
% keywords 'POINT_DATA' or 'CELL_DATA', followed by an integer number
% specifying the number of points of cells. Other keyword/data combination
% then define the actual dataset attribute values.
fprintf(fid, ['\nPOINT_DATA ' num2str(n_elements)]);
% Parse remaining argument.
vidx = find(strcmpi(varargin,'VECTORS'));
sidx = find(strcmpi(varargin,'SCALARS'));
if vidx~=0
for ii = 1:length(vidx)
title = varargin{vidx(ii)+1};
% Data enteries begin with a keyword specifying data type
% and numeric format.
fprintf(fid, ['\nVECTORS ', title,' float\n']);
output = [varargin{ vidx(ii) + 2 }(:)';...
varargin{ vidx(ii) + 3 }(:)';...
varargin{ vidx(ii) + 4 }(:)'];
if ~binaryflag
spec = ['%0.', precision, 'f '];
fprintf(fid, spec, output);
else
fwrite(fid, output, 'float', 'b');
end
% fwrite(fid, [reshape(varargin{vidx(ii)+2},1,n_elements);...
% reshape(varargin{vidx(ii)+3},1,n_elements);...
% reshape(varargin{vidx(ii)+4},1,n_elements)],'float','b');
end
end
if sidx~=0
for ii = 1:length(sidx)
title = varargin{sidx(ii)+1};
fprintf(fid, ['\nSCALARS ', title,' float\n']);
fprintf(fid, 'LOOKUP_TABLE default\n');
if ~binaryflag
spec = ['%0.', precision, 'f '];
fprintf(fid, spec, varargin{ sidx(ii) + 2});
else
fwrite(fid, varargin{ sidx(ii) + 2}, 'float', 'b');
end
% fwrite(fid, reshape(varargin{sidx(ii)+2},1,n_elements),'float','b');
end
end
case 'POLYDATA'
fprintf(fid, 'ASCII\n');
if numel(varargin)<4, error('Not enough input arguments'); end
x = varargin{2}(:);
y = varargin{3}(:);
z = varargin{4}(:);
if numel(varargin)<4, error('Not enough input arguments'); end
if sum(size(x)==size(y) & size(y)==size(z))~= length(size(x))
error('Input dimesions do not match')
end
n_elements = numel(x);
fprintf(fid, 'DATASET POLYDATA\n');
if mod(n_elements,3)==1
x(n_elements+1:n_elements+2,1)=[0;0];
y(n_elements+1:n_elements+2,1)=[0;0];
z(n_elements+1:n_elements+2,1)=[0;0];
elseif mod(n_elements,3)==2
x(n_elements+1,1)=0;
y(n_elements+1,1)=0;
z(n_elements+1,1)=0;
end
nbpoint = numel(x);
fprintf(fid, ['POINTS ' num2str(nbpoint) ' float\n']);
spec = [repmat(['%0.', precision, 'f '], 1, 9), '\n'];
output = [x(1:3:end-2), y(1:3:end-2), z(1:3:end-2),...
x(2:3:end-1), y(2:3:end-1), z(2:3:end-1),...
x(3:3:end), y(3:3:end), z(3:3:end)]';
fprintf(fid, spec, output);
switch upper(varargin{1})
case 'LINES'
if mod(n_elements,2)==0
nbLine = 2*n_elements-2;
else
nbLine = 2*(n_elements-1);
end
conn1 = zeros(nbLine,1);
conn2 = zeros(nbLine,1);
conn2(1:nbLine/2) = 1:nbLine/2;
conn1(1:nbLine/2) = conn2(1:nbLine/2)-1;
conn1(nbLine/2+1:end) = 1:nbLine/2;
conn2(nbLine/2+1:end) = conn1(nbLine/2+1:end)-1;
fprintf(fid,'\nLINES %d %d\n',nbLine,3*nbLine);
fprintf(fid,'2 %d %d\n',[conn1';conn2']);
case 'TRIANGLE'
ntri = length(varargin{5});
fprintf(fid,'\nPOLYGONS %d %d\n',ntri,4*ntri);
fprintf(fid,'3 %d %d %d\n',(varargin{5}-1)');
case 'TETRAHEDRON'
ntetra = length(varargin{5});
fprintf(fid,'\nPOLYGONS %d %d\n',ntetra,5*ntetra);
fprintf(fid,'4 %d %d %d %d\n',(varargin{5}-1)');
end
end
fclose(fid);
if strcmpi(filename,'matlab_export.vtk')
switch computer
case {'PCWIN','PCWIN64'}
!paraview.exe --data='matlab_export.vtk' &
% Exclamation point character is a shell escape, the rest of the
% input line will be sent to operating system. It can not take
% variables, though. The & at the end of line will return control to
% Matlab even when the outside process is still running.
case {'GLNXA64','MACI64'}
!paraview --data='matlab_export.vtk' &
end
end
end
function setdataformat(fid, binaryflag)
if ~binaryflag
fprintf(fid, 'ASCII\n');
else
fprintf(fid, 'BINARY\n');
end
end