Code covered by the BSD License  

Highlights from
Viewer3D

image thumbnail

Viewer3D

by

 

04 Nov 2008 (Updated )

MIP, Color, Slice and Shaded 3D (shearwarp) Volume Rendering, interactive 3D view/measurement GUI

viewer3d(varargin)
function varargout = viewer3d(varargin)
% VIEWER3D a Matlab 3D volume renderer using the fast shearwarp algorithm.
%
% VIEWER3D(V, RENDERTYPE, SCALES);
%
% inputs,
% V : 3D Input image volume, of type double, single, uint8, uint16 or
% uint32 
%            (the render process uses only double calculations)
% RENDERTYPE: 'MIP' Maximum Intensity Render (default)
%             'VR' Volume Rendering
%             'VRC' Volume Rendering Color
%             'VRS' Volume Rendering with Shading
% SCALES: The sizes(height, width, depth) of one voxel. (default [1 1 1])
%
% Volume Data, 
%  Range of V must be [0 1] in case of double or single. Volume Data of 
%  type double has shorter render times than data of uint8 or uint16.
%
% example,
%   % Load data
%   load TestVolume;
%   viewer3d(V);
%
% See also: render_mip, render_bw, render_color, render_shaded
%
% Function is written by D.Kroon University of Twente (November 2008)

% Edit the above text to modify the response to help viewer3d

% Last Modified by GUIDE v2.5 04-Nov-2008 14:16:11

% Begin initialization code - DO NOT EDIT
gui_Singleton = 0;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @viewer3d_OpeningFcn, ...
                   'gui_OutputFcn',  @viewer3d_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before viewer3d is made visible.
function viewer3d_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to viewer3d (see VARARGIN)

% Choose default command line output for viewer3d
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

%matlabpool(3);

% addpath mexcode and help
try
    functionname='viewer3d.m';
    functiondir=which(functionname);
    functiondir=functiondir(1:end-length(functionname));
    addpath([functiondir '/help'])
catch end
% Initialized data storage structure
data.mouse_pressed=false;
data.mouse_button='';

% Get input voxel volume and convert to double
if (isempty(varargin)), 
    data.volume=zeros(3,3,3);
    data.volume_preview=zeros(3,3,3);
else
    if(ndims(varargin{1})==3)
        data.volume=varargin{1};
        switch(class(data.volume))
            case {'uint8','uint16'}
            case 'single'
                data.volume(data.volume<0)=0; data.volume(data.volume>1)=1;
            case 'double'
                data.volume(data.volume<0)=0; data.volume(data.volume>1)=1;
            otherwise
                warning('viewer3d:inputs', 'Unsupported input datatype converted to double');
                data.volume=im2double(data.volume);
                data.volume(data.volume<0)=0; data.volume(data.volume>1)=1;
        end
        data.volume_preview=imresize3d(data.volume,[],[32 32 32],'linear');
    else
        error('viewer3d:inputs', 'Input image not 3 dimensional');
    end
end

% Get input render type
if(length(varargin)>1)
    switch lower(varargin{2})
    case 'mip'
        data.render_type='mip';
    case 'vr'
        data.render_type='vr';
    case 'vrc'
        data.render_type='vrc';
    case 'vrs'
        data.render_type='vrs';
    otherwise
        error('viewer3d:inputs', 'Render type unknown');
    end
else
    data.render_type='mip';
end

% Get input voxelvolume scaling
if(length(varargin)>2)
    Scales=varargin{3}; Scales=sqrt(3)*Scales./sqrt(sum(Scales.^2));
    data.viewer_matrix=[Scales(1) 0 0 0; 0 Scales(2) 0 0; 0 0 Scales(3) 0; 0 0 0 1];
else
    data.viewer_matrix=[1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 1];
end

data.handle_viewer3d=gcf;
data.handle_histogram=[];
data.histogram_positions = [0.2 0.4 0.6 0.9]; 
data.histogram_alpha = [0 0.5 0.35 1]; 
data.histogram_colors= [0 0 0; 1 0 0; 1 1 0; 1 1 1];
data.first_render=true;
data.axes_size=[400 400];
data.histogram_pointselected=[];
data.mouse_position_pressed=[0 0];
data.mouse_position=[0 0];
data.mouse_position_last=[0 0];
data.shading_material='shiny';
data=loadmousepointershapes(data);
data.handles=handles;
setMyData(data);
createAlphaColorTable();
% Show the data
show3d(false)

% UIWAIT makes viewer3d wait for user response (see UIRESUME)
% uiwait(handles.figure1);


function createAlphaColorTable()
% This function creates a Matlab colormap and alphamap from the markers
data=getMyData(); if(isempty(data)), return, end
    data.colortable=zeros(1000,3); 
    data.alphatable=zeros(1000,1);
    % Loop through all 256 color/alpha indexes
    for j=0:999
        i=j/999;
        if (i<data.histogram_positions(1)), alpha=0; color=data.histogram_colors(1,:);
        elseif(i>data.histogram_positions(end)), alpha=0; color=data.histogram_colors(end,:);
        elseif(i==data.histogram_positions(1)), alpha=data.histogram_alpha(1); color=data.histogram_colors(1,:);
        elseif(i==data.histogram_positions(end)), alpha=data.histogram_alpha(end); color=data.histogram_colors(end,:);
        else
            % Linear interpolate the color and alpha between markers
            index_down=find(data.histogram_positions<=i); index_down=index_down(end);
            index_up=find(data.histogram_positions>i); index_up=index_up(1);
            perc=(i-data.histogram_positions(index_down)) / (data.histogram_positions(index_up) - data.histogram_positions(index_down));
            color=(1-perc)*data.histogram_colors(index_down,:)+perc*data.histogram_colors(index_up,:);
            alpha=(1-perc)*data.histogram_alpha(index_down)+perc*data.histogram_alpha(index_up);
        end
        data.colortable(j+1,:)=color;
        data.alphatable(j+1)=alpha;
    end
setMyData(data);


function data=loadmousepointershapes(data)
I=1-(imread('icon_mouse_rotate1.png')>0); I(I==0)=NaN;
data.icon_mouse_rotate1=I;
I=1-(imread('icon_mouse_rotate2.png')>0); I(I==0)=NaN;
data.icon_mouse_rotate2=I;
I=1-(imread('icon_mouse_zoom.png')>0); I(I==0)=NaN;
data.icon_mouse_zoom=I;
I=1-(imread('icon_mouse_pan.png')>0); I(I==0)=NaN;
data.icon_mouse_pan=I;


function show3d(preview)
data=getMyData(); if(isempty(data)), return, end

% Calculate light and viewer vectors
data.ViewerVector = [0 0 1];
data.LightVector = [0.67 0.33 0.67];
    
if(preview)
    viewer_matrix=data.viewer_matrix*ResizeMatrix(size(data.volume_preview)./size(data.volume));
   
    switch data.render_type
    case 'mip'
        data.render_image = render_mip(data.volume_preview, data.axes_size(1:2), viewer_matrix);
    case 'vr'
        data.render_image = render_bw(data.volume_preview, data.axes_size(1:2), viewer_matrix, data.alphatable);
    case 'vrc'
        data.render_image = render_color(data.volume_preview, data.axes_size(1:2), viewer_matrix, data.alphatable, data.colortable);
    case 'vrs'
        data.render_image = render_shaded(data.volume_preview, data.axes_size(1:2), viewer_matrix, data.alphatable, data.colortable, data.LightVector, data.ViewerVector,data.shading_material);
    end
else
    set_mouse_shape('watch',data); pause(0.001);
    switch data.render_type
    case 'mip'
        data.render_image = render_mip(data.volume, data.axes_size(1:2), data.viewer_matrix);
    case 'vr'
        data.render_image = render_bw(data.volume, data.axes_size(1:2), data.viewer_matrix, data.alphatable);
    case 'vrc'
        data.render_image = render_color(data.volume, data.axes_size(1:2), data.viewer_matrix, data.alphatable, data.colortable);
    case 'vrs'
        data.render_image = render_shaded(data.volume, data.axes_size(1:2), data.viewer_matrix, data.alphatable, data.colortable, data.LightVector, data.ViewerVector,data.shading_material);
    end
    set_mouse_shape('arrow',data); pause(0.001);
end

if(data.first_render)
    data.imshow_handle=imshow(data.render_image); 
    data.first_render=false;
else
    set(data.imshow_handle,'Cdata',data.render_image);
end
data.axes_size=get(data.handles.axes3d,'PlotBoxAspectRatio');
set(get(data.handles.axes3d,'Children'),'ButtonDownFcn','viewer3d(''axes3d_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
setMyData(data);


% --- Outputs from this function are returned to the command line.
function varargout = viewer3d_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on mouse motion over figure - except title and menu.
function figure1_WindowButtonMotionFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
cursor_position_in_axes(hObject,handles);
data=getMyData(); if(isempty(data)), return, end
if(isempty(data)), return, end;
if(data.mouse_pressed)
    switch(data.mouse_button)
    case 'rotate1'
        r1=-360*(data.mouse_position_last(1)-data.mouse_position(1));
        r2=360*(data.mouse_position_last(2)-data.mouse_position(2));
        R=RotationMatrix([r1 r2 0]);
        data.viewer_matrix=R*data.viewer_matrix;
        setMyData(data);
        show3d(true)
    case 'rotate2'
        r1=100*(data.mouse_position_last(1)-data.mouse_position(1));
        r2=100*(data.mouse_position_last(2)-data.mouse_position(2));
        if(data.mouse_position(2)>0.5), r1=-r1; end
        if(data.mouse_position(1)<0.5), r2=-r2; end
        r3=r1+r2;
        R=RotationMatrix([0 0 r3]);
        data.viewer_matrix=R*data.viewer_matrix;
        setMyData(data);
        show3d(true)
    case 'pan'
        t2=200*(data.mouse_position_last(1)-data.mouse_position(1));
        t1=200*(data.mouse_position_last(2)-data.mouse_position(2));
        M=TranslateMatrix([t1 t2 0]);
        data.viewer_matrix=M*data.viewer_matrix;
        setMyData(data);
        show3d(true)      
    case 'zoom'
        z1=1+2*(data.mouse_position_last(1)-data.mouse_position(1));
        z2=1+2*(data.mouse_position_last(2)-data.mouse_position(2));
        z=0.5*(z1+z2); %sqrt(z1.^2+z2.^2);
        R=ResizeMatrix([z z z]); 
        data.viewer_matrix=R*data.viewer_matrix;
        setMyData(data);
        show3d(true)        
    otherwise
    end
end

function R=RotationMatrix(r)
% Determine the rotation matrix (View matrix) for rotation angles xyz ...
    Rx=[1 0 0 0; 0 cosd(r(1)) -sind(r(1)) 0; 0 sind(r(1)) cosd(r(1)) 0; 0 0 0 1];
    Ry=[cosd(r(2)) 0 sind(r(2)) 0; 0 1 0 0; -sind(r(2)) 0 cosd(r(2)) 0; 0 0 0 1];
    Rz=[cosd(r(3)) -sind(r(3)) 0 0; sind(r(3)) cosd(r(3)) 0 0; 0 0 1 0; 0 0 0 1];
    R=Rx*Ry*Rz;
    
function M=ResizeMatrix(s)
	M=[1/s(1) 0 0 0;
	   0 1/s(2) 0 0;
	   0 0 1/s(3) 0;
	   0 0 0 1];

function M=TranslateMatrix(t)
	M=[1 0 0 -t(1);
	   0 1 0 -t(2);
	   0 0 1 -t(3);
	   0 0 0 1];
 
function cursor_position_in_axes(hObject,handles)
data=getMyData(); 
if(isempty(data)), return, end;
data.mouse_position_last=data.mouse_position;
% Get position of the mouse in the large axes
p = get(0, 'PointerLocation');
pf = get(hObject, 'pos');
p(1:2) = p(1:2)-pf(1:2);
set(gcf, 'CurrentPoint', p(1:2));
p = get(handles.axes3d, 'CurrentPoint');
data.mouse_position=[p(1, 1) p(1, 2)]./data.axes_size(1:2);
setMyData(data);

function setMyData(data)
% Store data struct in figure
setappdata(gcf,'data3d',data);

function data=getMyData()
% Get data struct stored in figure
data=getappdata(gcf,'data3d');

% --- Executes on mouse press over axes background.
function axes3d_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to axes3d (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
data.mouse_pressed=true;
data.mouse_button=get(handles.figure1,'SelectionType');
if(strcmp(data.mouse_button,'normal'))
    if(sum((data.mouse_position-[0.5 0.5]).^2)<0.15)
        data.mouse_button='rotate1';
        set_mouse_shape('rotate1',data)
    else
        data.mouse_button='rotate2';
        set_mouse_shape('rotate2',data)
    end
end
if(strcmp(data.mouse_button,'extend'))
    data.mouse_button='pan';
    set_mouse_shape('pan',data)
end
if(strcmp(data.mouse_button,'alt'))
    data.mouse_button='zoom';
    set_mouse_shape('zoom',data)
end
data.mouse_position_pressed=data.mouse_position;
setMyData(data);

function set_mouse_shape(type,data)

switch(type)
case 'rotate1'
    set(gcf,'Pointer','custom','PointerShapeCData',data.icon_mouse_rotate1,'PointerShapeHotSpot',round(size(data.icon_mouse_rotate1)/2))
    set(data.handles.figure1,'Pointer','custom');
case 'rotate2'
    set(gcf,'Pointer','custom','PointerShapeCData',data.icon_mouse_rotate2,'PointerShapeHotSpot',round(size(data.icon_mouse_rotate2)/2))
    set(data.handles.figure1,'Pointer','custom');
case 'zoom'
    set(gcf,'Pointer','custom','PointerShapeCData',data.icon_mouse_zoom,'PointerShapeHotSpot',round(size(data.icon_mouse_zoom)/2))
    set(data.handles.figure1,'Pointer','custom');
case 'pan'
    set(gcf,'Pointer','custom','PointerShapeCData',data.icon_mouse_pan,'PointerShapeHotSpot',round(size(data.icon_mouse_pan)/2))
    set(data.handles.figure1,'Pointer','custom');
otherwise
    set(data.handles.figure1,'Pointer',type);
end
    



% --- Executes on mouse press over figure background, over a disabled or
% --- inactive control, or over an axes background.
function figure1_WindowButtonUpFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
data.mouse_pressed=false;
setMyData(data);
show3d(false)
set(handles.figure1,'Pointer','arrow');


function A=imresize3d(V,scale,tsize,ntype,npad)
% This function resizes a 3D image volume to new dimensions
% Vnew = imresize3d(V,scale,nsize,ntype,npad);
%
% inputs,
%   V: The input image volume
%   scale: scaling factor, when used set tsize to [];
%   nsize: new dimensions, when used set scale to [];
%   ntype: Type of interpolation ('nearest', 'linear', or 'cubic')
%   npad: Boundary condition ('replicate', 'symmetric', 'circular', 'fill', or 'bound')  
%
% outputs,
%   Vnew: The resized image volume
%
% example,
%   load('mri','D'); D=squeeze(D);
%   Dnew = imresize3d(D,[],[80 80 40],'nearest','bound');
%
% This function is written by D.Kroon University of Twente (July 2008)
% Check the inputs
if(exist('ntype', 'var') == 0), ntype='nearest'; end
if(exist('npad', 'var') == 0), npad='bound'; end
if(exist('scale', 'var')&&~isempty(scale)), tsize=round(size(V)*scale); end
if(exist('tsize', 'var')&&~isempty(tsize)),  scale=(tsize./size(V)); end

% Make transformation structure   
T = makehgtform('scale',scale);
tform = maketform('affine', T);

% Specify resampler
R = makeresampler(ntype, npad);

% Resize the image volueme
A = tformarray(V, tform, R, [1 2 3], [1 2 3], tsize, [], 0);


function [Mshear,Mwarp2D,c]=matrixshearwarp(Mview,sizes)

% Find the principal viewing axis
Vo=[Mview(1,2)*Mview(2,3) - Mview(2,2)*Mview(1,3);
    Mview(2,1)*Mview(1,3) - Mview(1,1)*Mview(2,3);
    Mview(1,1)*Mview(2,2) - Mview(2,1)*Mview(1,2)];

[maxv,c]=max(abs(Vo));

% Choose the corresponding Permutation matrix P
switch(c)
    case 1, %yzx
        P=[0 1 0 0;
           0 0 1 0;
           1 0 0 0;
           0 0 0 1;];
    case 2, % zxy
        P=[0 0 1 0;
           1 0 0 0;
           0 1 0 0;
           0 0 0 1;];
    case 3, % xyz
        P=[1 0 0 0;
           0 1 0 0;
           0 0 1 0;
           0 0 0 1;];
end

% Compute the permuted view matrix from Mview and P
Mview_p=Mview*inv(P);

% 180 degrees rotate detection
if(Mview_p(3,3)<0), c=c+3; end

% Compute the shear coeficients from the permuted view matrix
Si = (Mview_p(2,2)* Mview_p(1,3) - Mview_p(1,2)* Mview_p(2,3)) / (Mview_p(1,1)* Mview_p(2,2) - Mview_p(2,1)* Mview_p(1,2));
Sj = (Mview_p(1,1)* Mview_p(2,3) - Mview_p(2,1)* Mview_p(1,3)) / (Mview_p(1,1)* Mview_p(2,2) - Mview_p(2,1)* Mview_p(1,2));

% Compute the translation between the orgins of standard object coordinates
% and intermdiate image coordinates

if((c==1)||(c==4)), kmax=sizes(1)-1; end
if((c==2)||(c==5)), kmax=sizes(2)-1; end
if((c==3)||(c==6)), kmax=sizes(3)-1; end

if ((Si>=0)&&(Sj>=0)), Ti = 0;        Tj = 0;        end
if ((Si>=0)&&(Sj<0)),  Ti = 0;        Tj = -Sj*kmax; end
if ((Si<0)&&(Sj>=0)),  Ti = -Si*kmax; Tj = 0;        end
if ((Si<0)&&(Sj<0)),   Ti = -Si*kmax; Tj = -Sj*kmax; end

% Compute the shear matrix 
Mshear=[1  0 Si Ti;
        0  1 Sj Tj;
        0  0  1  0;
        0  0  0  1];
        
% Compute the 2Dwarp matrix
Mwarp2D=[Mview_p(1,1) Mview_p(1,2) (Mview_p(1,4)-Ti*Mview_p(1,1)-Tj*Mview_p(1,2)); 
         Mview_p(2,1) Mview_p(2,2) (Mview_p(2,4)-Ti*Mview_p(2,1)-Tj*Mview_p(2,2)); 
               0           0                                  1                  ];

% Compute the 3Dwarp matrix
% Mwarp3Da=[Mview_p(1,1) Mview_p(1,2) (Mview_p(1,3)-Si*Mview_p(1,1)-Sj*Mview_p(1,2)) Mview_p(1,4); 
%           Mview_p(2,1) Mview_p(2,2) (Mview_p(2,3)-Si*Mview_p(2,1)-Sj*Mview_p(2,2)) Mview_p(2,4); 
%           Mview_p(3,1) Mview_p(3,2) (Mview_p(3,3)-Si*Mview_p(3,1)-Sj*Mview_p(3,2)) Mview_p(3,4); 
%                 0           0                                  0                        1      ];
% Mwarp3Db=[1 0 0 -Ti;
%           0 1 0 -Tj;
%           0 0 1   0;
%           0 0 0   1];
% Mwarp3D=Mwarp3Da*Mwarp3Db;
% % Control matrix Mview
% Mview_control = Mwarp3D*Mshear*P;
% disp(Mview)
% disp(Mview_control)


% --------------------------------------------------------------------
function menu_file_Callback(hObject, eventdata, handles)
% hObject    handle to menu_file (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function menu_config_Callback(hObject, eventdata, handles)
% hObject    handle to menu_config (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function menu_change_alpha_colors_Callback(hObject, eventdata, handles)
% hObject    handle to menu_change_alpha_colors (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
data.handle_histogram=viewer3d_histogram(data.handle_viewer3d);
handles_histogram=guidata(data.handle_histogram);
data.handle_histogram_axes=handles_histogram.axes_histogram;
setMyData(data);
createHistogram();
drawHistogramPoints();

% --------------------------------------------------------------------
function menu_load_view_Callback(hObject, eventdata, handles)
% hObject    handle to menu_load_view (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
dataold=getMyData();
dataold.volume=[];
if(ishandle(dataold.handle_histogram)), close(dataold.handle_histogram); end
uiload();
if(exist('data','var'))
    data.first_render=true;
    data.handle_viewer3d=dataold.handle_viewer3d;
    data.handles.axes3d=dataold.handles.axes3d;
    data.handles.figure1=dataold.handles.figure1;
    setMyData(data);
    createAlphaColorTable();
    show3d(false);
else
    viewer3d_error({'Matlab File does not contain','data from "Save Render"'})
end


% --------------------------------------------------------------------
function menu_save_view_Callback(hObject, eventdata, handles)
% hObject    handle to menu_save_view (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
uisave('data');


function menu_load_histogram_Callback(hObject, eventdata, handles)
% hObject    handle to menu_load_view (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
alpha=0;
uiload;
if(exist('positions','var'))
    data.histogram_positions=positions;
    data.histogram_colors=colors;
    data.histogram_alpha=alpha;
    setMyData(data);
    drawHistogramPoints();
    createAlphaColorTable();
    show3d(false);
else
    viewer3d_error({'Matlab File does not contain','data from "Save AlphaColors"'})
end

% --------------------------------------------------------------------
function menu_save_histogram_Callback(hObject, eventdata, handles)
% hObject    handle to menu_save_view (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
positions=data.histogram_positions;
colors=data.histogram_colors;
alpha=data.histogram_alpha;
uisave({'positions','colors','alpha'});

% --------------------------------------------------------------------
function menu_render_Callback(hObject, eventdata, handles)
% hObject    handle to menu_render (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function menu_render_Mip_Callback(hObject, eventdata, handles)
% hObject    handle to menu_render_Mip (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
data.render_type='mip';
data.first_render=true;
setMyData(data);
show3d(false);

% --------------------------------------------------------------------
function menu_render_vr_Callback(hObject, eventdata, handles)
% hObject    handle to menu_render_vr (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
data.render_type='vr';
data.first_render=true;
setMyData(data);
show3d(false);


% --------------------------------------------------------------------
function menu_render_vrc_Callback(hObject, eventdata, handles)
% hObject    handle to menu_render_vrc (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
data.render_type='vrc';
data.first_render=true;
setMyData(data);
show3d(false);


% --------------------------------------------------------------------
function menu_render_vrs_Callback(hObject, eventdata, handles)
% hObject    handle to menu_render_vrs (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
data.render_type='vrs';
data.first_render=true;
setMyData(data);
show3d(false);


% --------------------------------------------------------------------
function menu_info_Callback(hObject, eventdata, handles)
% hObject    handle to menu_info (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --------------------------------------------------------------------
function menu_save_picture_Callback(hObject, eventdata, handles)
% hObject    handle to menu_save_picture (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[filename, pathname] = uiputfile({'*.png';'*.jpg'}, 'Save Rendered Image as');
data=getMyData(); if(isempty(data)), return, end
imwrite(data.render_image,[pathname filename]);


% --------------------------------------------------------------------
function menu_about_Callback(hObject, eventdata, handles)
% hObject    handle to menu_about (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
viewer3d_about


   
function createHistogram()
% This function creates and show the (log) histogram of the data    
data=getMyData(); if(isempty(data)), return, end
    % Get histogram
    [data.histogram_countsy, data.histogram_countsx]=imhist(data.volume(:));
    % Log the histogram data
    data.histogram_countsy=log(data.histogram_countsy+100); data.histogram_countsy=data.histogram_countsy-min(data.histogram_countsy);
    data.histogram_countsx=data.histogram_countsx./max(data.histogram_countsx(:));
    data.histogram_countsy=data.histogram_countsy./max(data.histogram_countsy(:));
    % Focus on histogram axes
    figure(data.handle_histogram)    
    % Display the histogram
    stem(data.handle_histogram_axes,data.histogram_countsx,data.histogram_countsy,'Marker', 'none'); 
    hold(data.handle_histogram_axes,'on'); 
    % Set the axis of the histogram axes
    data.histogram_maxy=max(data.histogram_countsy(:));
    data.histogram_maxx=max(data.histogram_countsx(:));
    
    set(data.handle_histogram_axes,'yLim', [0 1]);
    set(data.handle_histogram_axes,'xLim', [0 1]);
setMyData(data);

% --- Executes on selection change in popupmenu_colors.
function popupmenu_colors_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenu_colors (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns popupmenu_colors contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu_colors
data=getMyData(); if(isempty(data)), return, end
    % Generate the new color markers
    c_choice=get(handles.popupmenu_colors,'Value');
    ncolors=length(data.histogram_positions);
    switch c_choice,
        case 1,new_colormap=jet(1000); 
        case 2, new_colormap=hsv(1000);
        case 3, new_colormap=hot(1000);
        case 4, new_colormap=cool(1000);
        case 5, new_colormap=spring(1000);
        case 6, new_colormap=summer(1000);
        case 7, new_colormap=autumn(1000);
        case 8, new_colormap=winter(1000);
        case 9, new_colormap=gray(1000);
        case 10, new_colormap=bone(1000);
        case 11, new_colormap=copper(1000);
        case 12, new_colormap=pink(1000);
        otherwise, new_colormap=hot(1000);
    end
    new_colormap=new_colormap(round(1:(end-1)/(ncolors-1):end),:);
    data.histogram_colors=new_colormap;
    
    % Draw the new color markers and make the color and alpha map
setMyData(data);
    drawHistogramPoints();
    createAlphaColorTable();
    show3d(false);



function drawHistogramPoints()
data=getMyData(); if(isempty(data)), return, end
    % Delete old points and line
    try
        delete(data.histogram_linehandle), 
        for i=1:length(data.histogram_pointhandle), 
           delete(data.histogram_pointhandle(i)), 
        end, 
    catch
    end
    stem(data.handle_histogram_axes,data.histogram_countsx,data.histogram_countsy,'Marker', 'none'); 
    hold(data.handle_histogram_axes,'on');
    
    % Display the markers and line through the markers.
    data.histogram_linehandle=plot(data.handle_histogram_axes,data.histogram_positions,data.histogram_alpha*data.histogram_maxy,'m');
    set(data.histogram_linehandle,'ButtonDownFcn','viewer3d(''lineHistogramButtonDownFcn'',gcbo,[],guidata(gcbo))');
    for i=1:length(data.histogram_positions)
        data.histogram_pointhandle(i)=plot(data.handle_histogram_axes,data.histogram_positions(i),data.histogram_alpha(i)*data.histogram_maxy,'bo','MarkerFaceColor',data.histogram_colors(i,:));
        set(data.histogram_pointhandle(i),'ButtonDownFcn','viewer3d(''pointHistogramButtonDownFcn'',gcbo,[],guidata(gcbo))');
    end
    
    % For detection of mouse up, down and motion in histogram figure.
    set(data.handle_histogram, 'WindowButtonDownFcn','viewer3d(''HistogramButtonDownFcn'',gcbo,[],guidata(gcbo))');
    set(data.handle_histogram, 'WindowButtonMotionFcn','viewer3d(''HistogramButtonMotionFcn'',gcbo,[],guidata(gcbo))');
    set(data.handle_histogram, 'WindowButtonUpFcn','viewer3d(''HistogramButtonUpFcn'',gcbo,[],guidata(gcbo))');
setMyData(data);    

function pointHistogramButtonDownFcn(hObject, eventdata, handles)
data=getMyData(); if(isempty(data)), return, end
data.mouse_button=get(data.handle_histogram,'SelectionType');
if(strcmp(data.mouse_button,'normal'))
    data.histogram_pointselected=find(data.histogram_pointhandle==gcbo);
    data.histogram_pointselectedhandle=gcbo;
    set(data.histogram_pointselectedhandle, 'MarkerSize',8);
    setMyData(data);
elseif(strcmp(data.mouse_button,'extend'))
    data.histogram_pointselected=find(data.histogram_pointhandle==gcbo);
    data.histogram_colors(data.histogram_pointselected,:)=rand(1,3);
    data.histogram_pointselected=[];
    setMyData(data);
    drawHistogramPoints();
    createAlphaColorTable();
    show3d(false);
elseif(strcmp(data.mouse_button,'alt'))
    data.histogram_pointselected=find(data.histogram_pointhandle==gcbo);

    data.histogram_positions(data.histogram_pointselected)=[];
    data.histogram_colors(data.histogram_pointselected,:)=[];
    data.histogram_alpha(data.histogram_pointselected)=[];

    data.histogram_pointselected=[];
    setMyData(data);
    drawHistogramPoints();
    createAlphaColorTable();
    show3d(false);
end


function HistogramButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

function HistogramButtonUpFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
if(~isempty(data.histogram_pointselected))
    set(data.histogram_pointselectedhandle, 'MarkerSize',6);
    data.histogram_pointselected=[];
    setMyData(data);
    createAlphaColorTable();
    % Show the data
    show3d(false)
end

function HistogramButtonMotionFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
cursor_position_in_histogram_axes(hObject,handles);
data=getMyData(); if(isempty(data)), return, end
if(~isempty(data.histogram_pointselected))
 % Set point to location mouse
        data.histogram_positions(data.histogram_pointselected)=data.histogram_mouse_position(1,1); 
        data.histogram_alpha(data.histogram_pointselected)=data.histogram_mouse_position(1,2);
        
        % Correct new location
        if(data.histogram_alpha(data.histogram_pointselected)<0), data.histogram_alpha(data.histogram_pointselected)=0; end
        if(data.histogram_alpha(data.histogram_pointselected)>1), data.histogram_alpha(data.histogram_pointselected)=1; end
        if(data.histogram_positions(data.histogram_pointselected)<0), data.histogram_positions(data.histogram_pointselected)=0; end
        if(data.histogram_positions(data.histogram_pointselected)>1), data.histogram_positions(data.histogram_pointselected)=1; end
        if((data.histogram_pointselected>1)&&(data.histogram_positions(data.histogram_pointselected-1)>data.histogram_positions(data.histogram_pointselected)))
            data.histogram_positions(data.histogram_pointselected)=data.histogram_positions(data.histogram_pointselected-1);
        end
        
        if((data.histogram_pointselected<length(data.histogram_positions))&&(data.histogram_positions(data.histogram_pointselected+1)<data.histogram_positions(data.histogram_pointselected)))
            data.histogram_positions(data.histogram_pointselected)=data.histogram_positions(data.histogram_pointselected+1);
        end

        % Move point
        set(data.histogram_pointselectedhandle, 'xdata', data.histogram_positions(data.histogram_pointselected));
        set(data.histogram_pointselectedhandle, 'ydata', data.histogram_alpha(data.histogram_pointselected));
        
        % Move line
        set(data.histogram_linehandle, 'xdata',data.histogram_positions);
        set(data.histogram_linehandle, 'ydata',data.histogram_alpha);
end
setMyData(data);


function lineHistogramButtonDownFcn(hObject, eventdata, handles)
data=getMyData(); if(isempty(data)), return, end
        % New point on mouse location
        newposition=data.histogram_mouse_position(1,1);
        
        % List for the new markers
        newpositions=zeros(1,length(data.histogram_positions)+1);
        newalphas=zeros(1,length(data.histogram_alpha)+1);
        newcolors=zeros(size(data.histogram_colors,1)+1,3);

        % Check if the new point is between old points
        index_down=find(data.histogram_positions<=newposition); 
        if(isempty(index_down)) 
        else
            index_down=index_down(end);
            index_up=find(data.histogram_positions>newposition); 
            if(isempty(index_up)) 
            else
                index_up=index_up(1);
                
                % Copy the (first) old markers to the new lists
                newpositions(1:index_down)=data.histogram_positions(1:index_down);
                newalphas(1:index_down)=data.histogram_alpha(1:index_down);
                newcolors(1:index_down,:)=data.histogram_colors(1:index_down,:);
                
                % Add the new interpolated marker
                perc=(newposition-data.histogram_positions(index_down)) / (data.histogram_positions(index_up) - data.histogram_positions(index_down));
                color=(1-perc)*data.histogram_colors(index_down,:)+perc*data.histogram_colors(index_up,:);
                alpha=(1-perc)*data.histogram_alpha(index_down)+perc*data.histogram_alpha(index_up);
                
                newpositions(index_up)=newposition; 
                newalphas(index_up)=alpha; 
                newcolors(index_up,:)=color;
              
                % Copy the (last) old markers to the new lists
                newpositions(index_up+1:end)=data.histogram_positions(index_up:end);
                newalphas(index_up+1:end)=data.histogram_alpha(index_up:end);
                newcolors(index_up+1:end,:)=data.histogram_colors(index_up:end,:);
        
                % Make the new lists the used marker lists
                data.histogram_positions=newpositions; 
                data.histogram_alpha=newalphas; 
                data.histogram_colors=newcolors;
            end
        end
        
        % Update the histogram window
        cla(data.handle_histogram_axes);
setMyData(data);
drawHistogramPoints();
createAlphaColorTable();
show3d(false);

        


function cursor_position_in_histogram_axes(hObject,handles)
data=getMyData(); if(isempty(data)), return, end
    % Get position of the mouse in the large axes
    p = get(0, 'PointerLocation');
    pf = get(hObject, 'pos');
    p(1:2) = p(1:2)-pf(1:2);
    set(data.handle_histogram, 'CurrentPoint', p(1:2));
    p = get(data.handle_histogram_axes, 'CurrentPoint');
    data.histogram_mouse_position=[p(1, 1) p(1, 2)];
setMyData(data);


% --------------------------------------------------------------------
function menu_help_Callback(hObject, eventdata, handles)
% hObject    handle to menu_help (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
web('info.html');

% --- Executes when user attempts to close figure1.
function figure1_CloseRequestFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: delete(hObject) closes the figure
data=getMyData(); if(isempty(data)), return, end
try
delete(data.handle_histogram);
catch end
try
rmappdata(gcf,'data3d');
catch end
delete(hObject);


% parallel
% matlabpool close;


% --------------------------------------------------------------------
function menu_shiny_Callback(hObject, eventdata, handles)
% hObject    handle to menu_shiny (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
data.shading_material='shiny';
setMyData(data);
show3d(false);

% --------------------------------------------------------------------
function menu_dull_Callback(hObject, eventdata, handles)
% hObject    handle to menu_dull (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
data.shading_material='dull';
setMyData(data);
show3d(false);

% --------------------------------------------------------------------
function menu_metal_Callback(hObject, eventdata, handles)
% hObject    handle to menu_metal (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
data.shading_material='metal';
setMyData(data);
show3d(false);


% --------------------------------------------------------------------
function menu_rendersize400_Callback(hObject, eventdata, handles)
% hObject    handle to menu_rendersize400 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
data.axes_size=[400 400];
data.first_render=true;
setMyData(data);
show3d(false);


% --------------------------------------------------------------------
function menu_rendersize800_Callback(hObject, eventdata, handles)
% hObject    handle to menu_rendersize800 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
data=getMyData(); if(isempty(data)), return, end
data.axes_size=[800 800];
data.first_render=true;
setMyData(data);
show3d(false);


Contact us