Diff of /vol3d.m [000000] .. [f949a5]

Switch to unified view

a b/vol3d.m
1
function [model] = vol3d(varargin)
2
3
%H = VOL3D Volume render 3-D data. 
4
% VOL3D uses the orthogonal plane 2-D texture mapping technique for 
5
% volume rending 3-D data in OpenGL. Use the 'texture' option to fine 
6
% tune the texture mapping technique. This function is best used with
7
% fast OpenGL hardware.
8
%
9
% vol3d                   Provide a demo of functionality.
10
%
11
% H = vol3d('CData',data) Create volume render object from input 
12
%                         3-D data. Use interp3 on data to increase volume
13
%                         rendering resolution. Returns a struct 
14
%                         encapsulating the pseudo-volume rendering object.
15
%                         XxYxZ array represents scaled colormap indices.
16
%                         XxYxZx3 array represents truecolor RGB values for
17
%                         each voxel (along the 4th dimension).
18
%
19
% vol3d(...,'Alpha',alpha) XxYxZ array of alpha values for each voxel, in
20
%                          range [0,1]. Default: data (interpreted as
21
%                          scaled alphamap indices).
22
%
23
% vol3d(...,'Parent',axH)  Specify parent axes. Default: gca.
24
%
25
% vol3d(...,'XData',x)  1x2 x-axis bounds. Default: [0 size(data, 2)].
26
% vol3d(...,'YData',y)  1x2 y-axis bounds. Default: [0 size(data, 1)].
27
% vol3d(...,'ZData',z)  1x2 z-axis bounds. Default: [0 size(data, 3)].
28
%
29
% vol3d(...,'texture','2D')  Only render texture planes parallel to nearest
30
%                            orthogonal viewing plane. Requires doing
31
%                            vol3d(h) to refresh if the view is rotated
32
%                            (i.e. using cameratoolbar).
33
%
34
% vol3d(...,'texture','3D')  Default. Render x,y,z texture planes
35
%                            simultaneously. This avoids the need to
36
%                            refresh the view but requires faster OpenGL
37
%                            hardware peformance.
38
%
39
% vol3d(H)  Refresh view. Updates rendering of texture planes 
40
%           to reduce visual aliasing when using the 'texture'='2D'
41
%           option.
42
%
43
% NOTES
44
% Use vol3dtool (from the original vol3d FEX submission) for editing the
45
% colormap and alphamap. Adjusting these maps will allow you to explore
46
% your 3-D volume data at various intensity levels. See documentation on 
47
% alphamap and colormap for more information.
48
%
49
% Use interp3 on input date to increase/decrease resolution of data
50
%
51
% Examples:
52
%
53
% % Visualizing fluid flow
54
% v = flow(50);
55
% h = vol3d('cdata',v,'texture','2D');
56
% view(3); 
57
% % Update view since 'texture' = '2D'
58
% vol3d(h);  
59
% alphamap('rampdown'), alphamap('decrease'), alphamap('decrease')
60
% 
61
% % Visualizing MRI data
62
% load mri.mat
63
% D = squeeze(D);
64
% h = vol3d('cdata',D,'texture','3D');
65
% view(3);  
66
% axis tight;  daspect([1 1 .4])
67
% alphamap('rampup');
68
% alphamap(.06 .* alphamap);
69
%
70
% See also alphamap, colormap, opengl, isosurface
71
72
% Copyright Joe Conti, 2004
73
% Improvements by Oliver Woodford, 2008-2011, with permission of the
74
% copyright holder.
75
76
if nargin == 0
77
    demo_vol3d;
78
    return
79
end
80
81
if isstruct(varargin{1})
82
    model = varargin{1};
83
    if length(varargin) > 1
84
       varargin = {varargin{2:end}};
85
    end
86
else
87
    model = localGetDefaultModel;
88
end
89
90
if length(varargin)>1
91
  for n = 1:2:length(varargin)
92
    switch(lower(varargin{n}))
93
        case 'cdata'
94
            model.cdata = varargin{n+1};
95
        case 'parent'
96
            model.parent = varargin{n+1};
97
        case 'texture'
98
            model.texture = varargin{n+1};
99
        case 'alpha'
100
            model.alpha = varargin{n+1};
101
        case 'xdata'
102
            model.xdata = varargin{n+1}([1 end]);
103
        case 'ydata'
104
            model.ydata = varargin{n+1}([1 end]);
105
        case 'zdata'
106
            model.zdata = varargin{n+1}([1 end]);
107
    end
108
    
109
  end
110
end
111
112
if isempty(model.parent)
113
    model.parent = gca;
114
end
115
116
[model] = local_draw(model);
117
118
%------------------------------------------%
119
function [model] = localGetDefaultModel
120
121
model.cdata = [];
122
model.alpha = [];
123
model.xdata = [];
124
model.ydata = [];
125
model.zdata = [];
126
model.parent = [];
127
model.handles = [];
128
model.texture = '3D';
129
tag = tempname;
130
model.tag = ['vol3d_' tag(end-11:end)];
131
132
%------------------------------------------%
133
function [model,ax] = local_draw(model)
134
135
cdata = model.cdata; 
136
siz = size(cdata);
137
138
% Define [x,y,z]data
139
if isempty(model.xdata)
140
    model.xdata = [0 siz(2)];
141
end
142
if isempty(model.ydata)
143
    model.ydata = [0 siz(1)];
144
end
145
if isempty(model.zdata)
146
    model.zdata = [0 siz(3)];
147
end
148
149
try
150
   delete(model.handles);
151
catch
152
end
153
154
ax = model.parent;
155
cam_dir = camtarget(ax) - campos(ax);
156
[m,ind] = max(abs(cam_dir));
157
158
opts = {'Parent',ax,'cdatamapping',[],'alphadatamapping',[],'facecolor','texturemap','edgealpha',0,'facealpha','texturemap','tag',model.tag};
159
160
if ndims(cdata) > 3
161
    opts{4} = 'direct';
162
else
163
    cdata = double(cdata);
164
    opts{4} = 'scaled';
165
end
166
167
if isempty(model.alpha)
168
    alpha = cdata;
169
    if ndims(model.cdata) > 3
170
        alpha = sqrt(sum(double(alpha).^2, 4));
171
        alpha = alpha - min(alpha(:));
172
        alpha = 1 - alpha / max(alpha(:));
173
    end
174
    opts{6} = 'scaled';
175
else
176
    alpha = model.alpha;
177
    if ~isequal(siz(1:3), size(alpha))
178
        error('Incorrect size of alphamatte');
179
    end
180
    opts{6} = 'none';
181
end
182
183
h = findobj(ax,'type','surface','tag',model.tag);
184
for n = 1:length(h)
185
  try
186
     delete(h(n));
187
  catch
188
  end
189
end
190
191
is3DTexture = strcmpi(model.texture,'3D');
192
handle_ind = 1;
193
194
% Create z-slice
195
if(ind==3 || is3DTexture )    
196
  x = [model.xdata(1), model.xdata(2); model.xdata(1), model.xdata(2)];
197
  y = [model.ydata(1), model.ydata(1); model.ydata(2), model.ydata(2)];
198
  z = [model.zdata(1), model.zdata(1); model.zdata(1), model.zdata(1)];
199
  diff = model.zdata(2)-model.zdata(1);
200
  delta = diff/size(cdata,3);
201
  for n = 1:size(cdata,3)
202
203
   cslice = squeeze(cdata(:,:,n,:));
204
   aslice = double(squeeze(alpha(:,:,n)));
205
   h(handle_ind) = surface(x,y,z,cslice,'alphadata',aslice,opts{:});
206
   z = z + delta;
207
   handle_ind = handle_ind + 1;
208
  end
209
210
end
211
212
% Create x-slice
213
if (ind==1 || is3DTexture ) 
214
  x = [model.xdata(1), model.xdata(1); model.xdata(1), model.xdata(1)];
215
  y = [model.ydata(1), model.ydata(1); model.ydata(2), model.ydata(2)];
216
  z = [model.zdata(1), model.zdata(2); model.zdata(1), model.zdata(2)];
217
  diff = model.xdata(2)-model.xdata(1);
218
  delta = diff/size(cdata,2);
219
  for n = 1:size(cdata,2)
220
221
   cslice = squeeze(cdata(:,n,:,:));
222
   aslice = double(squeeze(alpha(:,n,:)));
223
   h(handle_ind) = surface(x,y,z,cslice,'alphadata',aslice,opts{:});
224
   x = x + delta;
225
   handle_ind = handle_ind + 1;
226
  end
227
end
228
229
% Create y-slice
230
if (ind==2 || is3DTexture)
231
  x = [model.xdata(1), model.xdata(1); model.xdata(2), model.xdata(2)];
232
  y = [model.ydata(1), model.ydata(1); model.ydata(1), model.ydata(1)];
233
  z = [model.zdata(1), model.zdata(2); model.zdata(1), model.zdata(2)];
234
  diff = model.ydata(2)-model.ydata(1);
235
  delta = diff/size(cdata,1);
236
  for n = 1:size(cdata,1)
237
238
   cslice = squeeze(cdata(n,:,:,:));
239
   aslice = double(squeeze(alpha(n,:,:)));
240
   h(handle_ind) = surface(x,y,z,cslice,'alphadata',aslice,opts{:});
241
   y = y + delta;
242
   handle_ind = handle_ind + 1;
243
  end
244
end
245
246
model.handles = h;
247
248
function demo_vol3d
249
figure;
250
load mri.mat
251
vol3d('cdata', squeeze(D), 'xdata', [0 1], 'ydata', [0 1], 'zdata', [0 0.7]);
252
colormap(bone(256));
253
alphamap([0 linspace(0.1, 0, 255)]);
254
axis equal off
255
set(gcf, 'color', 'w');
256
view(3);