📄 sliceomatic.m
字号:
function sliceomatic(p1,p2,xmesh,ymesh,zmesh)% SLICEOMATIC - Slice and isosurface volume exploration GUI%% SLICEOMATIC(DATA) - Use 3D double matrix DATA as a volume data%% Example:%% [x,y,z] = meshgrid(-2:.2:2, -2:.25:2, -2:.16:2);% v = x .* exp(-x.^2 - y.^2 - z.^2);% sliceomatic(v)%% Using SLICEOMATIC with no arguments is equivalent to the above% example.%% SLICEOMATIC(DATA, X, Y, Z) - Run sliceomatic using the specified data % coordinates for the volume DATA. X, Y, and Z are the vectors over which% DATA is defined.%% ex:% x = -2:.2:2; y = -2:.25:2; z = -2:.16:2;% [X,Y,Z,] = meshgrid(x,y,z);% v = X .* exp(-X.^2 - Y.^2 - Z.^2);% sliceomatic(v,x,y,z)%%% Using the GUI:% -------------%% Create/Delete slices:% % The white bars on the top, left, and right allow insertion of% new slices on the X, Y, and Z planes. Click in an empty area to% add a new slice or surface. Right click on a control arrow to% reconfigure or delete that slice.%% Create/Delete isosurfaces:%% The colored bar at the bottom is used to place and position an% isosurface. The color in the bar indicates a position (as seen% in the slice) where the isosurface will go. Right click on a% control arrow to reconfigure or delete the isosurface.%% Orientation of the view:%% When the rotate camera button is on, the popup menu will control% the camera. Turn off camera rotation in order to get individual% control over properties of the slices and isosurfaces.%% Changing Defaults:%% The defaults menu provides default features of newly created% slices and surfaces. The AllSlices menu controls properties of% all the slices and surfaces in the scene. Use popup menus on the% objects themselves, or the control arrows to change indivudual% properties.%% Color & Alpha Maps:%% The Colormap popdown controls the currenlty active colormap.% This map is used to color the slices. The Alphamap popdown% controls the alphamap used on the slices.%% Use the color or alpha maps to change how areas of your data are% highlighted.%% Controls Control:%% The Controls menu allows you to adjust how the controls look. An% important feature here is the "Animate" item. You can enable or% disable an animation when some changes are made. Since this is% decorative, it may be important to turn this off for large data% sets.%% Doing Cool Stuff:% ----------------%% Exploration:% You can get a quick feel of the current data set by adding a% slice using the ColorTexture option. Such a slice can be dragged% through the data very quickly.%% Highlight an Area:% If certain values in your data are interesting (very large, very% small, or very median values) you can use transparency to make% parts of your slices disappear. Choose AlphaTexture options from% the defaults, and sweep some slices across your data. Use the% AlphaMap to pick out certain data sets. The exaple given here% looks best with the `vdown' alphamap.%% Contours on slices:% You can add a contour onto a slice to further extract shapes% from the data you are exploring. Auto-selecting contour limits% will choose contours on a per slice basis. Auto-selecting% contour lines from a volume arbitrarily specifies 10 levels% based on the limits of the volume.%% Hidden Shapes:% Use the isosurface control bar to create an isosurface. Be% patient with this control. It often takes a while for the% surface to be created. Click and hold the mouse button down% until the first surface appears. Drag the surface through the% values until you get something you like, then let go. If your% data set is very large, you will need to wait while the new and% more accurate isosurface is created.%% Volumes:% You can simulate a volume object by creating lots of stacked% slices. Simply use the proper Alphamap and transparent textures% to highlight the correct data, and a large stack of slices will% let you simulate a volume object.%% Customized Graphics:% -------------------%% To add your own graphics into the sliceomatic display, whatever% that may be, you can use the following technique:%% 1) click on a control arrow% 2) use gco to get the data for that object% slice = getappdata(gco,'arrowslice')% 3) use GET to get the cdata and position data which you can use% to add your own graphics.%% Setting Default Values:% ----------------------%% If you want to change some default setup feature of sliceomatic,% use the "Save Preferences" menu item. Future sliceomatic% sessions will then retrieve those settings.%%% BUGS:% ----%% 1) Inaccurate Slice% Sliceomatic does not use the `slice' command. All slices are% created by explicitly extracting data from the volume. As such,% only slices at integer values are allowed.% % 2) Crashes MATLAB% Sliceomatic uses the default OpenGL setup. If you encounter% frequent crashes you can start by enabling software OpenGL% rendering. This should always fix the problem, and would% likely slow things down too. You should also update your% graphics driver for your video card. On Windows, in% particular, drivers are updated frequently. For detail on how% to overcome these problems, visit this web page:% http://www.mathworks.com/support/tech-notes/1200/1201.html%% See Also: SLICE, ISOSURFACE, ISOCAPS, CONTOURC, COLORMAP, SURFACE % This is version 2.2 of sliceomatic.%% Sliceomatic is a tool I wrote for fun. There are no warrenties% expressed or implied.% Written by Eric Ludlam <eludlam@mathworks.com>% Copyright 2000, 2001, 2002, 2003, 2004, 2005 The MathWorks Inc%% Modified by Emiliano Spezi <emiliano.spezi@physics.org>% Added capability: axes limits control, slice leveling controls,% and contour level specification.% Last modified: 22 May 2003 if nargin==0 [x,y,z] = meshgrid(-2:.2:2, -2:.25:2, -2:.16:2); v = x .* exp(-x.^2 - y.^2 - z.^2); sliceomatic(v) return end if isa(p1,'double')% $$$ if nargin==4% $$$ d.Xv=p1;% $$$ d.Yv=p2;% $$$ d.Zv=p3% $$$ p1=p4;% $$$ else% $$$ d.Yv=1:size(p1,1);% $$$ d.Xv=1:size(p1,2);% $$$ d.Zv=1:size(p1,3);% $$$ end d.data=p1; if nargin>=4 if nargin==4 zmesh=ymesh; ymesh=xmesh; xmesh=p2; end d = sliceomaticfigure(d,xmesh,ymesh,zmesh); d = sliceomaticsetdata(d,xmesh,ymesh,zmesh); else d = sliceomaticfigure(d); d = sliceomaticsetdata(d); end setappdata(gcf,'sliceomatic',d); elseif isa(p1,'char') % Interpret commands d=getappdata(gcf,'sliceomatic'); try switch p1 case 'Xnew' if strcmp(get(gcf,'selectiontype'),'normal') pt=get(gcbo,'currentpoint'); axis(gcbo); X=pt(1,1); newa=arrow(gcbo,'down',[X 0]); set(gcf,'currentaxes',d.axmain); new=localslice(d.data, X, [], []); setappdata(new,'controlarrow',newa); setappdata(newa(2),'arrowslice',new); set(new,'alphadata',get(new,'cdata'),'alphadatamapping','scaled'); set(newa,'buttondownfcn','sliceomatic Xmove'); set([new newa],'uicontextmenu',d.uic); % Make sure whatever buttonupfcn on the figure is run now to "turn % off" whatever was going on before we got our callback on the % arrow. buf = get(gcf,'windowbuttonupfcn'); if ~strcmp(buf,'') eval(buf); end d.draggedarrow=newa(2); dragprep(newa(2)); setpointer(gcf,'SOM leftright'); set(d.motionmetaslice,'visible','off'); end case 'Ynew' if strcmp(get(gcf,'selectiontype'),'normal') pt=get(gcbo,'currentpoint'); Y=pt(1,2); newa=arrow(gcbo,'right',[0 Y]); set(gcf,'currentaxes',d.axmain); new=localslice(d.data, [], Y, []); setappdata(new,'controlarrow',newa); setappdata(newa(2),'arrowslice',new); set(new,'alphadata',get(new,'cdata'),'alphadatamapping','scaled'); set(newa,'buttondownfcn','sliceomatic Ymove'); set([new newa],'uicontextmenu',d.uic); % Make sure whatever buttonupfcn on the figure is run now to "turn % off" whatever was going on before we got our callback on the % arrow. buf = get(gcf,'windowbuttonupfcn'); if ~strcmp(buf,'') eval(buf); end d.draggedarrow=newa(2); dragprep(newa(2)); setpointer(gcf,'SOM topbottom'); set(d.motionmetaslice,'visible','off'); end % if strcmp(get(gcf, case 'Znew' if strcmp(get(gcf,'selectiontype'),'normal') pt=get(gcbo,'currentpoint'); Y=pt(1,2); newa=arrow(gcbo,'left', [0 Y]); set(gcf,'currentaxes',d.axmain); new=localslice(d.data, [], [], Y); set(new,'alphadata',get(new,'cdata'),'alphadatamapping','scaled'); setappdata(new,'controlarrow',newa); setappdata(newa(2),'arrowslice',new); set(newa,'buttondownfcn','sliceomatic Zmove'); set([new newa],'uicontextmenu',d.uic); % Make sure whatever buttonupfcn on the figure is run now to "turn % off" whatever was going on before we got our callback on the % arrow. buf = get(gcf,'windowbuttonupfcn'); if ~strcmp(buf,'') eval(buf); end d.draggedarrow=newa(2); dragprep(newa(2)); setpointer(gcf,'SOM topbottom'); set(d.motionmetaslice,'visible','off'); end % if strcmp(get(gcf, case 'ISO' if strcmp(get(gcf,'selectiontype'),'normal') pt=get(gcbo,'currentpoint'); V=pt(1,1); newa=arrow(gcbo,'up',[V 0]); set(gcf,'currentaxes',d.axmain); new=localisosurface(d.reducelims,d.reduce,d.reducesmooth,V); set([newa new],'uicontextmenu',d.uiciso); setappdata(new,'controlarrow',newa); setappdata(new,'reduced',1); setappdata(newa(2),'arrowiso',new); set(newa,'buttondownfcn','sliceomatic ISOmove'); % Make sure whatever buttonupfcn on the figure is run now to "turn % off" whatever was going on before we got our callback on the % arrow. buf = get(gcf,'windowbuttonupfcn'); if ~strcmp(buf,'') eval(buf); end d.draggedarrow=newa(2); dragprep(newa(2)); setpointer(gcf,'SOM leftright'); end % if strcmp(get(gcf, case 'Xmove' if strcmp(get(gcf,'selectiontype'),'normal') [a s]=getarrowslice; d.draggedarrow=a; dragprep(a); end case 'Ymove' if strcmp(get(gcf,'selectiontype'),'normal') [a s]=getarrowslice; d.draggedarrow=a; dragprep(a); end case 'Zmove' if strcmp(get(gcf,'selectiontype'),'normal') [a s]=getarrowslice; d.draggedarrow=a; dragprep(a); end case 'ISOmove' if strcmp(get(gcf,'selectiontype'),'normal') [a s]=getarrowslice; d.draggedarrow=a; dragprep(a); end case 'up' if strcmp(get(gcf,'selectiontype'),'normal') dragfinis(d.draggedarrow); end case 'motion' % Make sure our cursor is ok a=d.draggedarrow; % The arrow being dragged s=getappdata(a,'arrowslice'); % The slice to 'move' if isempty(s) s=getappdata(a,'arrowiso'); % or the isosurface end aa=get(a,'parent'); % arrow's parent axes pos=getappdata(a,'arrowcenter'); % the line the arrow points at. apos=get(aa,'currentpoint'); % Bind the axes position to the limits of that axes. xlimits = get(aa,'xlim'); ylimits = get(aa,'ylim'); if apos(1,1) < xlimits(1) apos(1,1) = xlimits(1); elseif apos(1,1) > xlimits(2) apos(1,1) = xlimits(2); end if apos(1,2) < ylimits(1) apos(1,2) = ylimits(1); elseif apos(1,2) > ylimits(2) apos(1,2) = ylimits(2); end if aa==d.axx || aa==d.axiso % We are moving an X slice xdiff=apos(1,1)-pos(1,1); v=get(a,'vertices'); v(:,1)=v(:,1)+xdiff; set([a getappdata(a,'arrowedge')],'vertices',v); np=[ apos(1,1) 0 ]; % This might be a slice, or an isosurface! if aa==d.axiso new=localisosurface(d.reducelims,d.reduce,d.reducesmooth,... apos(1,1),s); setappdata(new,'reduced',1); movetipforarrow(a, aa, apos(1,1), [ apos(1,1) 6 ], 'bottom','center') else %disp([ 'apos = ' num2str(apos(1,1))]) %disp([ 'pos = ' num2str(pos(1,1))]) %disp([ 'change=' num2str(round(apos(1,1))~=round(pos(1,1)))]); if round(apos(1,1))~=round(pos(1,1)) localslice(d.data, apos(1,1), [], [],s); end movetipforarrow(a, aa, apos(1,1), [ apos(1,1) .5 ],'top','center') end else % We are moving a Y or Z slice ydiff=apos(1,2)-pos(1,2); v=get(a,'vertices'); v(:,2)=v(:,2)+ydiff; set([a getappdata(a,'arrowedge')],'vertices',v); np=[ 0 apos(1,2) ]; if aa==d.axy if round(apos(1,2))~=round(pos(1,2)) localslice(d.data, [], apos(1,2), [], s); end movetipforarrow(a, aa, apos(1,2), [ 5.5 apos(1,2) ], 'middle','left'); else if round(apos(1,2))~=round(pos(1,2)) localslice(d.data, [], [], apos(1,2), s); end movetipforarrow(a, aa, apos(1,2), [ .5 apos(1,2) ], 'middle','right'); end end setappdata(a,'arrowcenter',np); % This improves anaimation speed in Java Figures/R14 % The Rule: Java Figures don't want this drawnow. try if isempty(get(gcf,'javaframe')) drawnow; end catch drawnow; end % % IsoSurface context menu items % case 'isotogglevisible' [a s]=getarrowslice; if propcheck(s,'visible','on') set(s,'visible','off'); else set(s,'visible','on'); end case 'isodelete' [a s]=getarrowslice; if numel(a)==1 delete(getappdata(a,'arrowedge')); end cap=getappdata(s,'sliceomaticisocap'); if ~isempty(cap) delete(cap); end delete(s); delete(a); case 'isoflatlight' [a s]=getarrowslice; set(s,'facelighting','flat'); case 'isosmoothlight' [a s]=getarrowslice; set(s,'facelighting','phong'); case 'isocolor' [a s]=getarrowslice; c=uisetcolor(get(s,'facecolor')); slowset(s,'facecolor',c,d.animincrement); case 'isoalpha' [a s]=getarrowslice; if nargin ~= 2 error('Not enough arguments to sliceomatic.'); end slowset(s,'facealpha',eval(p2),d.animincrement); case 'isocaps' [a s]=getarrowslice; cap=getappdata(s,'isosurfacecap'); if isempty(cap) new=localisocaps(s); set(new,'uicontextmenu',d.uiciso); else delete(cap); setappdata(s,'isosurfacecap',[]); end % % Now for slice context menu items % case 'togglevisible' [a s]=getarrowslice; switch get(s,'visible') case 'on' set(s,'visible','off'); pushset(a,'facealpha',.2); case 'off' set(s,'visible','on'); popset(a,'facealpha'); end case 'setfaceted' [a s]=getarrowslice; set(s,'edgec','k','facec','flat'); if ischar(get(s,'facea')) && strcmp(get(s,'facea'),'texturemap') set(s,'facea','flat'); end textureizeslice(s,'off'); case 'setflat' [a s]=getarrowslice; set(s,'edgec','n','facec','flat'); if ischar(get(s,'facea')) && strcmp(get(s,'facea'),'texturemap') set(s,'facea','flat'); end textureizeslice(s,'off'); case 'setinterp' [a s]=getarrowslice; set(s,'edgec','n','facec','interp'); if ischar(get(s,'facea')) && strcmp(get(s,'facea'),'texturemap') set(s,'facea','interp'); end textureizeslice(s,'off');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -