bound2im matlab 安装,img2mesh.m

function varargout = img2mesh(varargin)

%

% Format:

% newworkspace = img2mesh or imgmesh(workspace)

%

% A GUI for Iso2Mesh for streamlined mesh data processing

%

% Author: Qianqian Fang

%

% Input:

% workspace (optional): a struct containing the below fields

% .graph: a digraph object containing the i2m workspace data

% Output:

% newworkspace (optional): the updated workspace, with the same

% subfields as the input.

%

% If a user supplys an output variable, the GUI will not return until

% the user closes the window; if a user does not provide any output,

% the call will return immediately.

%

% Please find more information at http://iso2mesh.sf.net/

%

% -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)

%

% Begin initialization code - DO NOT EDIT

gui_Singleton = 1;

gui_State = struct('gui_Name', mfilename, ...

'gui_Singleton', gui_Singleton, ...

'gui_OpeningFcn', @i2m_OpeningFcn, ...

'gui_OutputFcn', @i2m_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 i2m is made visible.

function i2m_OpeningFcn(hObject, eventdata, handles, varargin)

cm = uicontextmenu;

uimenu(cm,'Label','Plot','CallBack',{@processdata,handles});

uimenu(cm,'Label','Rename','CallBack',{@processdata,handles});

uimenu(cm,'Label','Delete','CallBack',{@processdata,handles});

mimeshing = uimenu(cm,'Label','Meshing');

miv2s = uimenu(mimeshing,'Label','Volume to surface','CallBack',{@processdata,handles});

uimenu(mimeshing,'Label','Volume to mesh','CallBack',{@processdata,handles});

uimenu(mimeshing,'Label','Surface to mesh','CallBack',{@processdata,handles});

uimenu(mimeshing,'Label','Surface to volume','CallBack',{@processdata,handles});

uimenu(mimeshing,'Label','Close and fill volume','CallBack',{@processdata,handles});

uimenu(mimeshing,'Label','Extract surface','CallBack',{@processdata,handles});

uimenu(mimeshing,'Label','Tessellate surface','CallBack',{@processdata,handles});

mirepair = uimenu(cm,'Label','Surface repair');

uimenu(mirepair,'Label','Clean surface','CallBack',{@processdata,handles});

uimenu(mirepair,'Label','Repair surface','CallBack',{@processdata,handles});

uimenu(mirepair,'Label','Smooth surface','CallBack',{@processdata,handles});

uimenu(mirepair,'Label','Simplify surface','CallBack',{@processdata,handles});

uimenu(mirepair,'Label','Remesh surface','CallBack',{@processdata,handles});

uimenu(mirepair,'Label','Simplify surface','CallBack',{@processdata,handles});

uimenu(mirepair,'Label','Reorient mesh elements','CallBack',{@processdata,handles});

mibool = uimenu(cm,'Label','Surface boolean');

uimenu(mibool,'Label','Or','CallBack',{@processdata,handles});

uimenu(mibool,'Label','And','CallBack',{@processdata,handles});

uimenu(mibool,'Label','All','CallBack',{@processdata,handles});

uimenu(mibool,'Label','Diff','CallBack',{@processdata,handles});

uimenu(mibool,'Label','First','CallBack',{@processdata,handles});

uimenu(mibool,'Label','Second','CallBack',{@processdata,handles});

mireport = uimenu(cm,'Label','Report');

uimenu(mireport,'Label','Containing data','CallBack',{@processdata,handles});

uimenu(mireport,'Label','Mesh quality histogram','CallBack',{@processdata,handles});

uimenu(mireport,'Label','Element volume histogram','CallBack',{@processdata,handles});

uimenu(mireport,'Label','Total volume','CallBack',{@processdata,handles});

mirefresh=uimenu(cm,'Label','Refresh','CallBack',{@miRefresh_Callback,handles});

uimenu(cm,'Label','Save as','CallBack',{@processdata,handles});

miv2s.Separator='on';

mimeshing.Separator='on';

mirefresh.Separator='on';

root=get(handles.fgI2M,'userdata');

if(isempty(root))

root=struct('graph',digraph,'menu',cm);

end

set(handles.fgI2M,'userdata',root);

set(handles.axFlow,'position',[0 0 1 1]);

set(handles.axPreview,'position',[0 0 1 1]);

set(handles.fgI2M,'UIContextMenu',handles.meCreate);

axis(handles.axFlow,'off');

axis(handles.axPreview,'off');

% Choose default command line output for i2m

handles.output = hObject;

% Update handles structure

guidata(hObject, handles);

% UIWAIT makes i2m wait for user response (see UIRESUME)

% uiwait(handles.fgI2M);

function processdata(source,callbackdata,handles)

try

obj=get(handles.fgI2M,'currentobject');

if(strcmp(class(obj),'matlab.graphics.chart.primitive.GraphPlot')==0)

if(~isempty(obj.UserData) && strcmp(class(obj.UserData),'matlab.graphics.chart.primitive.GraphPlot'))

obj=obj.UserData;

else

return

end

end

root=get(handles.fgI2M,'userdata');

pos=get(handles.axFlow,'currentpoint');

[nodedata,nodetype,nodeid]=getnodeat(root,obj,pos);

newtype=dummytype;

prefix='x';

switch source.Label

case 'Volume to surface'

if(isstruct(nodetype) && isfield(nodetype,'hasvol') && nodetype.hasvol)

[newdata,newtype]=v2sgui(nodedata);

prefix='Vol2Surf';

else

error('no volume data found');

end

case 'Volume to mesh'

if(nodetype.hasvol)

[newdata,newtype]=v2mgui(nodedata);

prefix='Vol2Mesh';

else

error('no volume data found');

end

case 'Surface to mesh'

if(nodetype.hasnode && nodetype.hasface)

[newdata,newtype]=s2mgui(nodedata);

prefix='Surf2Mesh';

else

error('no surface data found');

end

case 'Surface to volume'

if(nodetype.hasnode && nodetype.hasface)

ndiv = inputdlg('Division number along the shortest dimension:',...

'surf2vol - rasterizing a surface mesh',1,{'50'});

if(isempty(ndiv))

return;

end

newdata.vol=s2v(nodedata.node,nodedata.face,str2num(ndiv{1}));

newtype.hasvol=1;

prefix='Surf2Vol';

else

error('no surface data found');

end

case 'Close and fill volume'

if(nodetype.hasvol)

rad=inputdlg('maximum gap length in voxel (scalar)','Close and fill a volume',1,{'1'});

newdata.vol=fillholes3d(nodedata.vol,str2num(rad{1}));

newtype=nodetype;

prefix='FillVol';

else

error('no volume data found');

end

case 'Extract surface'

if(isstruct(nodetype) && isfield(nodetype,'hasvol') && nodetype.hasvol)

[newdata.node,newdata.face]=binsurface(nodedata.vol);

prefix='BinSurf';

elseif(nodetype.hasnode && nodetype.haselem)

newdata.node=nodedata.node;

newdata.face=volface(nodedata.elem(:,1:min(4,size(nodedata.elem,2))));

[newdata.node,newdata.face]=removeisolatednode(newdata.node,newdata.face);

prefix='VolSurf';

elseif(nodetype.hasnode && nodetype.hasface)

[newdata.node,newdata.face]=deal(nodedata.node,nodedata.face);

prefix='CopySurf';

end

newtype.hasnode=1;

newtype.hasface=1;

case 'Clean surface'

if(nodetype.hasnode && nodetype.hasface)

[newdata.node,newdata.face]=meshcheckrepair(nodedata.node,nodedata.face,'deep');

newtype=nodetype;

prefix='CleanSurf';

else

error('no surface data found');

end

case 'Repair surface'

if(nodetype.hasnode && nodetype.hasface)

[newdata.node,newdata.face]=meshcheckrepair(nodedata.node,nodedata.face,'meshfix');

newtype=nodetype;

prefix='RepairSurf';

else

error('no surface data found');

end

case 'Smooth surface'

if(nodetype.hasnode && nodetype.hasface)

res = inputdlg({'Method (laplacian,laplacianhc,lowpass):','Iteration (integer):','Alpha (scalar):'},...

'sms - smoothing a surface mesh',[1,1,1],{'lowpass','20','0.5'});

if(isempty(res))

return;

end

newdata=nodedata;

newtype=nodetype;

newdata.node=sms(nodedata.node,nodedata.face,str2num(res{2}),str2num(res{3}),res{1});

prefix='SmoothSurf';

else

error('no surface data found');

end

case 'Simplify surface'

if(nodetype.hasnode && nodetype.hasface)

res = inputdlg('Percentage of edges to keep (0-1):',...

'Simplify mesh',[1],{'1'});

if(isempty(res))

return;

end

[newdata.node,newdata.face]=meshresample(nodedata.node,nodedata.face,str2num(res{1}));

newtype=nodetype;

prefix='SimplifySurf';

else

error('no surface data found');

end

case 'Remesh surface'

if(nodetype.hasnode && nodetype.hasface)

res = inputdlg({'Rasterization voxel size (scalar):','Max gap to close (scalar):','Max surface element radis (scalar):'},...

'Remesh surface',[1,1,1],{'1','20','3'});

if(isempty(res))

return;

end

opt.gridsize=str2num(res{1});

opt.closesize=str2num(res{2});

opt.elemsize=str2num(res{3});

[newdata.node, newdata.face]=remeshsurf(nodedata.node,nodedata.face,opt);

newtype.hasnode=1;

newtype.hasface=1;

prefix='RemeshSurf';

else

error('no surface data found');

end

case 'Tessellate surface'

if(nodetype.hasnode && nodetype.hasface)

[newdata.node,newdata.elem]=fillsurf(nodedata.node,nodedata.face);

newdata.face=volface(newdata.elem(:,1:min(4,size(newdata.elem,2))));

newtype=nodetype;

newtype.haselem=1;

prefix='TessMesh';

else

error('no surface data found');

end

case 'Reorient mesh elements'

if(nodetype.hasnode && nodetype.haselem)

[newdata.node,newdata.elem]=meshreorient(nodedata.node,nodedata.elem);

newtype=nodetype;

prefix='ReorientMesh';

elseif(nodetype.hasnode && nodetype.hasface)

[newdata.node,newdata.face]=surfreorient(nodedata.node,nodedata.face);

newtype=nodetype;

prefix='ReorientSurf';

else

error('no surface or tetrahedral mesh data found');

end

case 'Mesh quality histogram'

if(nodetype.hasnode && nodetype.haselem)

quality=meshquality(nodedata.node,nodedata.elem);

elseif(nodetype.hasnode && nodetype.hasface)

quality=meshquality(nodedata.node,nodedata.face);

end

if(exist('quality','var'))

figure;

hist(quality,50);

end

return;

case 'Element volume histogram'

if(nodetype.hasnode && nodetype.haselem)

evol=elemvolume(nodedata.node,nodedata.elem);

elseif(nodetype.hasnode && nodetype.hasface)

evol=elemvolume(nodedata.node,nodedata.face);

end

if(exist('evol','var'))

figure;

hist(evol,50);

end

return;

case 'Total volume'

if(nodetype.hasnode && nodetype.haselem)

evol=elemvolume(nodedata.node,nodedata.elem);

elseif(nodetype.hasnode && nodetype.hasface)

[no,el]=fillsurf(nodedata.node,nodedata.face);

evol=elemvolume(no,el);

end

if(exist('evol','var'))

msgbox(sprintf('Total volume is %f cubic voxel',sum(evol)),'Total volume');

end

return;

case 'Containing data'

msg='';

if(nodetype.hasnode)

msg=[msg sprintf('\nContaining %d nodes (%d columns)',size(nodedata.node,1),size(nodedata.node,2))];

end

if(nodetype.hasface)

msg=[msg sprintf('\nContaining %d triangles (%d columns)',size(nodedata.face,1),size(nodedata.face,2))];

end

if(nodetype.haselem)

msg=[msg sprintf('\nContaining %d tetrehedra (%d columns)',size(nodedata.elem,1),size(nodedata.elem,2))];

end

if(nodetype.hasvol)

msg=[msg sprintf('\nContaining [%d x %d x %d ] volume',size(nodedata.vol,1),size(nodedata.vol,2),size(nodedata.vol,3))];

end

msgbox(msg,'Mesh data report');

return;

case 'Plot'

if(isstruct(nodetype) && isfield(nodetype,'hasnode') && nodetype.hasnode)

if(isfield(nodetype,'haselem') && nodetype.haselem)

figure('keypressfcn',@plotfigevent,'userdata',struct('node',nodedata.node,'face',[],'elem',nodedata.elem));

plotmesh(nodedata.node,[],nodedata.elem);

else

figure('keypressfcn',@plotfigevent,'userdata',struct('node',nodedata.node,'elem',[],'face',nodedata.face));

plotmesh(nodedata.node,nodedata.face);

end

else

figure('keypressfcn',@plotfigevent,'userdata',struct('vol',nodedata.vol));

hs=slice(double(nodedata.vol),[],[ceil(size(nodedata.vol,2)*0.5)],ceil(size(nodedata.vol,3)*0.5));

set(hs,'linestyle','none');

end

case {'Or','And','Diff','All','First','Second'}

if(isstruct(nodetype) && isfield(nodetype,'hasnode'))

if((nodetype.hasface || nodetype.haselem) && nodetype.hasnode)

pt=ginput(1);

[nodedata2,nodetype2,nodeid2]=getnodeat(root,obj,pt);

if(~nodetype2.hasnode || ~nodetype2.hasface)

if(nodetype2.hasnode && nodetype2.haselem)

nodedata2.face=volface(nodedata2.elem);

else

error('Second operand does not contain a surface');

end

end

op=source.Label;

if(strcmp(op,'Intersect'))

op='inter';

end

if(~nodetype.hasface)

nodedata.face=volface(nodedata.elem);

end

[newdata.node,newdata.face]=surfboolean(nodedata.node,nodedata.face,lower(op),nodedata2.node,nodedata2.face(:,[1 3 2]));

newtype.hasnode=1;

newtype.hasface=1;

prefix=source.Label;

else

warndlg('Selected node does not contain a surface mesh');

end

end

case 'Delete'

button = questdlg('Are you sure to delete the selected node?', 'Confirm','No');

if strcmpi(button, 'No') || strcmpi(button, 'Cancel')

return;

end

root.graph=rmnode(root.graph,root.graph.Nodes.Name{nodeid});

updategraph(root,handles);

case 'Rename'

newname = inputdlg('Define a new name:',...

'Rename',1,{root.graph.Nodes.Name{nodeid}});

if(isempty(newname))

return;

end

if(isempty(newname{1}) || ~isempty(cell2mat(regexp( root.graph.Nodes.Name, ['^' newname{1} '$']))))

error('empty or duplicated node name');

end

root.graph.Nodes.Name{nodeid}=newname{1};

updategraph(root,handles);

case 'Save as'

if(~nodetype.haselem && ~nodetype.hasnode)

error('selected data does not have a mesh');

return;

end

filter = {'*.jmesh';'*.*'};

[file, path] = uiputfile(filter,'Export mesh');

if ~isequal(file,0) && ~isequal(path,0)

if(nodetype.haselem)

savejmesh(nodedata.node,nodedata.face,nodedata.elem,fullfile(path,file));

else

savejmesh(nodedata.node,nodedata.face,fullfile(path,file));

end

end

end

if(exist('newdata','var') && exist('newtype','var'))

cla(handles.axPreview);

cla(handles.axFlow);

newdata.preview=getpreview(newdata,newtype,[400,400]);

[newkey,root.graph]=addnodewithdata(handles,newdata,newtype,prefix);

root.graph=addedge(root.graph,{root.graph.Nodes.Name{nodeid}},{newkey});

if(strcmp(source.Parent.Type, 'uimenu') && strcmp(source.Parent.Label,'Surface boolean'))

root.graph=addedge(root.graph,{root.graph.Nodes.Name{nodeid2}},{newkey});

end

updategraph(root,handles);

end

catch ME

msg=sprintf('Error: \n%s\n',ME.message);

for e=1:length(ME.stack)

msg=sprintf('%s\nFile: %s\nFunction: %s\nLine: %d\n\n',msg,ME.stack(e).file,ME.stack(e).name,ME.stack(e).line);

end

uiwait(warndlg(msg,'I2M ERROR'));

updategraph(root,handles);

end

function plotfigevent(hobject,event)

data=get(hobject,'userdata');

plotpos=[];

if(isfield(data,'plotpos'))

plotpos=data.plotpos;

end

if(isempty(plotpos))

switch event.Key

case {'rightarrow','uparrow'}

plotpos=0;

case {'leftarrow','downarrow'}

plotpos=9;

otherwise

end

end

if(isfield(data,'node'))

pmax=max(data.node);

pmin=min(data.node);

cla;

switch event.Key

case 'rightarrow'

plotpos=min(plotpos+1,9);

plotmesh(data.node,data.face,data.elem,sprintf('x>%f',(pmax(1)-pmin(1))*plotpos*0.1+pmin(1)))

case 'leftarrow'

plotpos=max(plotpos-1,0);

plotmesh(data.node,data.face,data.elem,sprintf('x>%f',(pmax(1)-pmin(1))*plotpos*0.1+pmin(1)))

case 'uparrow'

plotpos=min(plotpos+1,9);

plotmesh(data.node,data.face,data.elem,sprintf('y>%f',(pmax(2)-pmin(2))*plotpos*0.1+pmin(2)))

case 'downarrow'

plotpos=max(plotpos-1,0);

plotmesh(data.node,data.face,data.elem,sprintf('y>%f',(pmax(2)-pmin(2))*plotpos*0.1+pmin(2)))

otherwise

end

end

data.plotpos=plotpos;

set(hobject,'userdata',data);

%----------------------------------------------------------------

function [nodedata,nodetype,nodeid]=getnodeat(root,obj,pos)

nodedist=[obj.XData(:)-pos(1,1) obj.YData(:)-pos(1,2)];

nodedist=sum(nodedist.*nodedist,2);

[mindist, nodeid]=min(nodedist);

nodedata=root.graph.Nodes.Data{nodeid};

nodetype=root.graph.Nodes.Type{nodeid};

%----------------------------------------------------------------

function mytype=dummytype

mytype.hasnode=0;

mytype.hasface=0;

mytype.haselem=0;

mytype.hasvol=0;

%----------------------------------------------------------------

function [newdata, newtype]=v2sgui(data)

prompt = {'Threshold (scalar or array):',...

'Surface element radius bound (scalar):',...

'Surface element distance bound (scalar)','Method: (cgalsurf,cgalmesh,simplify)'};

title = 'vol2surf - extracting surface mesh from volume';

dims = [1 1 1 1];

definput = {'0.5','5','1','cgalsurf'};

res = inputdlg(prompt,title,dims,definput);

newdata=[];

newtype=dummytype;

if(isempty(res))

return;

end

opt=struct('radbound',str2num(res{2}),'distbound',str2num(res{3}));

[newdata.node,newdata.face]=v2s(data.vol,eval(res{1}),opt, res{4});

newtype.hasnode=1;

newtype.hasface=1;

%----------------------------------------------------------------

function [newdata, newtype]=v2mgui(data)

prompt = {'Threshold (scalar or []):',...

'Surface element radius bound (scalar):',...

'Surface element distance bound (scalar)',...

'Max element volume (scalar):',...

'Method (cgalsurf,cgalmesh,simplify):'};

title = 'vol2mesh - extracting tet mesh from volume';

dims = [1 1 1 1 1];

definput = {'[]','5','1','30','cgalmesh'};

res = inputdlg(prompt,title,dims,definput);

newdata=[];

newtype=dummytype;

if(isempty(res))

return;

end

opt=struct('radbound',str2num(res{2}),'distbound',str2num(res{3}));

[newdata.node,newdata.elem,newdata.face]=v2m(data.vol,eval(res{1}),...

opt, res{4});

newtype.hasnode=1;

newtype.hasface=1;

newtype.haselem=1;

%----------------------------------------------------------------

function img=getpreview(nodedata,nodetype,imsize)

hfpreview=figure('visible', 'off');

ax=axes('parent',hfpreview,'Units','pixels','position',[1, 1, imsize(1), imsize(2)]);

if(isfield(nodetype,'haselem') && nodetype.haselem)

plotmesh(nodedata.node,[],nodedata.elem,'linestyle',':','edgealpha',0.3,'parent',ax);

elseif(isfield(nodetype,'hasface') && nodetype.hasface)

plotmesh(nodedata.node,nodedata.face,'linestyle','-','parent',ax);

elseif(isfield(nodetype,'hasvol') && nodetype.hasvol)

hs=slice(double(nodedata.vol),[],[ceil(size(nodedata.vol,2)*0.5)],ceil(size(nodedata.vol,3)*0.5),'parent',ax);

set(hs,'linestyle','none');

elseif(isfield(nodetype,'hasnode') && nodetype.hasnode)

plotmesh(nodedata.node,'.','parent',ax);

end

set(ax,'color','none')

axis(ax,'equal');

axis(ax,'off');

img=getframe(gca);

img=flipud(img.cdata);

delete(ax);

close(hfpreview);

%----------------------------------------------------------------

function [newdata, newtype]=s2mgui(data)

prompt = {'Simplification ratio (%edges to keep, 0-1):',...

'Max element volume (scalar):',...

'Method (tetgen,tetgen1.5,cgalpoly):',...

'Region seeds (N x 3 array):',...

'Hole seeds (N x 3 array):'};

title = 'surf2mesh - creating tet mesh from surfaces';

dims = [1 1 1 1 1];

definput = {'1','30','tetgen','[]','[]'};

res = inputdlg(prompt,title,dims,definput);

newdata=[];

newtype=dummytype;

if(isempty(res))

return;

end

[newdata.node,newdata.elem,newdata.face]=...

s2m(data.node,data.face,str2num(res{1}),...

str2num(res{2}),res{3},eval(res{4}),eval(res{5}));

newtype.hasnode=1;

newtype.hasface=1;

newtype.haselem=1;

% --- Outputs from this function are returned to the command line.

function varargout = i2m_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

handles.output=get(handles.fgI2M,'userdata');

varargout{1} = handles.output;

% --------------------------------------------------------------------

function miWeb_Callback(hObject, eventdata, handles)

web('http://iso2mesh.sourceforge.net');

% --------------------------------------------------------------------

function miDoc_Callback(hObject, eventdata, handles)

web('http://iso2mesh.sourceforge.net/cgi-bin/index.cgi?Doc');

% --------------------------------------------------------------------

function miAbout_Callback(hObject, eventdata, handles)

helpmsg={

'\bf\fontsize{12}I2M: An Integrated GUI for Iso2Mesh Meshing Toolbox\rm\fontsize{10}',

'',

'Copyright (c) 2018 Qianqian Fang ',

''

'Computational Optics&Translational Imaging Lab (http://fanglab.org)',

'Department of Bioengineering',

'Northeastern University',

'360 Huntington Ave, Boston, MA 02115, USA',

'',

'URL: http://iso2mesh.sourceforge.net',

''};

opt.Interpreter = 'tex';

opt.WindowStyle = 'modal';

msgbox(helpmsg,'About','help',opt);

% --------------------------------------------------------------------

function miSphere_Callback(hObject, eventdata, handles)

prompt = {'Center:','Radius (scalar):',...

'Surface element radius bound (scalar)',...

'Max element volume (scalar, 0 - only create surface):'};

title = 'Create Mesh';

dims = [1 1 1 1];

definput = {'[0 0 0]','50','6','20'};

res = inputdlg(prompt,title,dims,definput);

if(isempty(res))

return;

end

newtype=dummytype;

opt=str2num(res{3});

if(str2num(res{4})==0)

[newdata.node,newdata.face]=meshasphere(eval(res{1}),...

str2num(res{2}),opt);

else

[newdata.node,newdata.face,newdata.elem]=meshasphere(eval(res{1}),...

str2num(res{2}),opt, str2num(res{4}));

newtype.haselem=1;

end

newtype.hasnode=1;

newtype.hasface=1;

if(exist('newdata','var') && exist('newtype','var'))

newkey=addnodewithdata(handles,newdata,newtype,'Sphere');

end

% --------------------------------------------------------------------

function miBox_Callback(hObject, eventdata, handles)

prompt = {'Diagonal end point 1 (1x3 vector):','Diagonal end point 2 (1x3 vector):',...

'Surface element radius bound (scalar)',...

'Max element volume (scalar, 0 - only create surface):'};

title = 'Create Mesh';

dims = [1 1 1 1];

definput = {'[0 0 0]','[100 60 30]','6','30'};

res = inputdlg(prompt,title,dims,definput);

if(isempty(res))

return;

end

newtype=dummytype;

opt=str2num(res{3});

if(str2num(res{4})==0)

[newdata.node,newdata.face]=meshabox(eval(res{1}),eval(res{2}),opt);

else

[newdata.node,newdata.face,newdata.elem]=meshabox(eval(res{1}),...

eval(res{2}),opt, str2num(res{4}));

newtype.haselem=1;

end

newtype.hasnode=1;

newtype.hasface=1;

if(exist('newdata','var') && exist('newtype','var'))

newkey=addnodewithdata(handles,newdata,newtype,'Box');

end

% --------------------------------------------------------------------

function miCylinder_Callback(hObject, eventdata, handles)

prompt = {'Axis end-point 1','Axis end-point 2','Radius (scalar):',...

'Surface element radius bound (scalar)',...

'Max element volume (scalar, 0 - only create surface):',...

'Circle division:'};

title = 'Create Mesh';

dims = [1 1 1 1 1 1];

definput = {'[0 0 0]','[0 0 50]','10','3','20','20'};

res = inputdlg(prompt,title,dims,definput);

if(isempty(res))

return;

end

newtype=dummytype;

opt=str2num(res{4});

maxvol=str2num(res{5});

if(maxvol==0)

[newdata.node,newdata.face]=meshacylinder(eval(res{1}),eval(res{2}),...

str2num(res{3}),opt);

else

[newdata.node,newdata.face,newdata.elem]=meshacylinder(eval(res{1}),eval(res{2}),...

str2num(res{3}),opt,maxvol);

newtype.haselem=1;

end

newtype.hasnode=1;

newtype.hasface=1;

if(exist('newdata','var') && exist('newtype','var'))

newkey=addnodewithdata(handles,newdata,newtype,'Cyl');

end

% --------------------------------------------------------------------

function miLoadVol_Callback(hObject, eventdata, handles)

nodedata=struct;

nodetype=dummytype;

filters={'*.nii;*.hdr;*.img;*.tif;*.tiff;*.inr;*.bin;*.ubj','3D volume file (*.nii;*.hdr;*.img;*.tif;*.tiff;*.inr;*.bin;*.ubj)';...

'*.nii','Nifti file (*.nii)';...

'*.hdr;*.img','Analyze 7.5 file (*.hdr;*.img)';...

'*.tif;*.tiff','Multipage TIFF file (*.tif)';...

'*.inr','INR image (*.inr)';...

'*.bin','Binary file (*.bin)';...

'*.ubj','Universal JSON (*.ubj)';...

'*.*','All (*.*)'};

[file,path,idx] = uigetfile(filters);

if isequal(file,0)

return;

else

if(regexp(file,'\.[Nn][Ii][Ii]$'))

im=readnifti(fullfile(path,file));

nodedata.vol=im.img;

nodetype.hasvol=1;

elseif(regexp(file,'(\.[Hh][Dd][Rr]$|\.[Ii][Mm][Gg]$)'))

im=readnifti(fullfile(path,file));

nodedata.vol=im.img;

nodetype.hasvol=1;

elseif(regexp(file,'\.[Tt][Ii][Ff][Ff]*$'))

nodedata.vol=readmptiff(fullfile(path,file));

nodetype.hasvol=1;

elseif(regexp(file,'\.[Ii][Nn][Rr]$'))

nodedata.vol=readinr(fullfile(path,file));

nodetype.hasvol=1;

elseif(regexp(file,'\.[Bb][Ii][Nn]$'))

prompt = {'Dimension (1x3 vector):',...

'Datatype (short,float,double,integer,...):'};

title = 'Load generic binary file';

dims = [1 1];

definput = {'[]','short'};

[res,isok] = inputdlg(prompt,title,dims,definput);

if(isok==0)

return;

end

nodedata.vol=loadmc2(fullfile(path,file),eval(res{1}),res{2});

nodetype.hasvol=1;

elseif(regexp(file,'\.[Uu][Bb][Jj]$'))

nodedata=loadubjson(fullfile(path,file));

if(isstruct(nodedata) && isfield(nodedata,'vol'))

nodetype.hasvol=1;

end

end

end

if(exist('nodedata','var'))

nodetype=getnodetype(nodedata);

if(nodetype.hasvol)

addnodewithdata(handles,nodedata,nodetype,'Vol');

end

else

warndlg('no valid mesh data found','Warning');

end

% --------------------------------------------------------------------

function miLoadMesh_Callback(hObject, eventdata, handles)

nodedata=struct;

nodetype=dummytype;

filters={'*.jmesh;*.off;*.medit;*.smf;*.json','3D Mesh files (*.jmesh;*.off;*.medit;*.smf;*.json)';...

'*.jmesh','JSON mesh (*.jmesh)';...

'*.off','OFF file (*.off)';...

'*.medit','Medit file (*.medit)';...

'*.ele','Tetgen element mesh file (*.ele)';...

'*.json','JSON file (*.json)';'*.*','All (*.*)'};

[file,path,idx] = uigetfile(filters);

if isequal(file,0)

return;

else

if(regexp(file,'\.[Oo][Ff][Ff]$'))

[nodedata.node, nodedata.face]=readoff(fullfile(path,file));

elseif(regexp(file,'\.[Mm][Ee][Dd][Ii][Tt]$'))

[nodedata.node, nodedata.elem]=readmedit(fullfile(path,file));

elseif(regexp(file,'\.[Ee][Ll][Ee]$'))

[pathstr,name,ext] = fileparts(fullfile(path,file));

[nodedata.node, nodedata.elem]=readtetgen(fullfile(pathstr,name));

elseif(regexp(file,'\.[Jj][Mm][Ee][Ss][Hh]$'))

nodedata=importjmesh(fullfile(path,file));

elseif(regexp(file,'\.[Jj][Ss][Oo][Nn]$'))

nodedata=loadjson(fullfile(path,file));

end

end

if(exist('nodedata','var'))

adddatatograph(handles,nodedata);

else

warndlg('no valid mesh data found','Warning');

end

% --------------------------------------------------------------------

function miLoadSurf_Callback(hObject, eventdata, handles)

nodedata=struct;

nodetype=dummytype;

filters={'*.jmesh;*.off;*.asc;*.smf;*.smf;*.json','3D Mesh files (*.jmesh;*.off;*.asc;*.smf;*.smf;*.json)';...

'*.jmesh','JSON mesh (*.jmesh)';...

'*.off','OFF file (*.off)';...

'*.asc','ASC file (*.asc)';...

'*.gts','GNU Trangulated Surface file (*.gts)';...

'*.smf','Simple Model Format (*.smf)';...

'*.json','JSON file (*.json)';'*.*','All (*.*)'};

[file,path,idx] = uigetfile(filters);

if isequal(file,0)

return;

else

if(regexp(file,'\.[Oo][Ff][Ff]$'))

[nodedata.node, nodedata.face]=readoff(fullfile(path,file));

elseif(regexp(file,'\.[Aa][Ss][Cc]$'))

[nodedata.node, nodedata.face]=readasc(fullfile(path,file));

elseif(regexp(file,'\.[Gg][Tt][Ss]$'))

[nodedata.node, nodedata.face]=readgts(fullfile(path,file));

elseif(regexp(file,'\.[Ss][Mm][Ff]$'))

[nodedata.node, nodedata.face]=readsmf(fullfile(path,file));

elseif(regexp(file,'\.[Jj][Mm][Ee][Ss][Hh]$'))

nodedata=importjmesh(fullfile(path,file));

elseif(regexp(file,'\.[Jj][Ss][Oo][Nn]$'))

nodedata=loadjson(fullfile(path,file));

end

end

if(exist('nodedata','var'))

adddatatograph(handles,nodedata);

else

warndlg('no valid mesh data found','Warning');

end

% --------------------------------------------------------------------

function nodedata=importjmesh(filename)

data=loadjson(filename);

nodedata=struct;

if(isfield(data,'MeshNode'))

nodedata.node=data.MeshNode;

end

if(isfield(data,'MeshElem'))

nodedata.elem=data.MeshElem;

end

if(isfield(data,'MeshSurf'))

nodedata.face=data.MeshSurf;

end

if(isfield(data,'MeshNodeVal'))

nodedata.node(:,end+1:end+size(data.MeshNodeVal,2))=data.MeshNodeVal;

end

if(isfield(data,'MeshTetraVal'))

nodedata.elem(:,end+1:end+size(data.MeshTetraVal,2))=data.MeshTetraVal;

end

% --------------------------------------------------------------------

function adddatatograph(handles,nodedata)

nodetype=getnodetype(nodedata);

if(nodetype.haselem)

addnodewithdata(handles,nodedata,nodetype,'Tet');

elseif(nodetype.hasface)

addnodewithdata(handles,nodedata,nodetype,'Surf');

elseif(nodetype.hasnode)

addnodewithdata(handles,nodedata,nodetype,'Point');

elseif(nodetype.hasvol)

addnodewithdata(handles,nodedata,nodetype,'Vol');

end

% --- Executes during object creation, after setting all properties.

function axFlow_CreateFcn(hObject, eventdata, handles)

% hObject handle to axFlow (see GCBO)

% eventdata reserved - to be defined in a future version of MATLAB

% handles empty - handles not created until after all CreateFcns called

% Hint: place code in OpeningFcn to populate axFlow

% --- Executes during object creation, after setting all properties.

function fgI2M_CreateFcn(hObject, eventdata, handles)

% hObject handle to fgI2M (see GCBO)

% eventdata reserved - to be defined in a future version of MATLAB

% handles empty - handles not created until after all CreateFcns called

%--------------------------------------------------------------------

function nodetype=getnodetype(nodedata)

nodetype=dummytype;

if(~isstruct(nodedata))

return;

end

names=fieldnames(nodedata);

for i=1:length(names)

switch names{i}

case 'node'

nodetype.hasnode=1;

case 'face'

nodetype.hasface=1;

case 'elem'

nodetype.haselem=1;

case 'vol'

nodetype.hasvol=1;

end

dat=nodedata.(names{i});

if((isnumeric(dat) || islogical(dat)) && ndims(dat)==3)

nodetype.hasvol=1;

end

end

% --------------------------------------------------------------------

function [key,newgraph]=addnodewithdata(handles,nodedata,nodetype,name)

root=get(handles.fgI2M,'userdata');

if(isempty(root))

root=struct('graph',digraph,'menu',uicontextmenu);

end

if(nargin<4)

name='x';

end

id=1;

if(~isempty(root.graph.Nodes))

while(find(strcmp(root.graph.Nodes.Name,sprintf('%s%d',name,id))))

id=id+1;

end

end

key=sprintf('%s%d',name,id);

cla(handles.axPreview);

cla(handles.axFlow);

nodedata.preview=getpreview(nodedata,nodetype,[400,400]);

nodeprop=table({key},{nodedata},{nodetype},'VariableNames',{'Name','Data','Type'});

root.graph=addnode(root.graph,nodeprop);

if(nargout>1)

newgraph=root.graph;

end

updategraph(root, handles);

% --------------------------------------------------------------------

function hobj=updatepreview(root,obj,handles)

cla(handles.axPreview);

view(handles.axPreview,2)

nx=obj.XData(:);

ny=obj.YData(:);

nn=length(nx);

hold(handles.axPreview,'on');

dx=get(handles.axFlow,'xlim');

dy=get(handles.axFlow,'ylim');

wd=min([diff(dx) diff(dy)])/15;

hobj=zeros(1,nn);

set(handles.axPreview,'xlim',dx);

set(handles.axPreview,'ylim',dy);

dim=get(handles.axPreview,'dataaspectratio');

[wfig, hfig]=getwindowsize(handles.fgI2M);

wfig=wfig*dim(2);

hfig=hfig*dim(1);

for i=1:nn

if(isfield(root.graph.Nodes.Data{i},'preview'))

hobj(i)=imagesc(nx(i)+[-2*wd 0], ny(i)+[-wd wd]*(wfig/hfig), imresize(root.graph.Nodes.Data{i}.preview,0.25), ...

'parent',handles.axPreview);

end

end

set(hobj,'userdata',obj);

set(hobj,'UIContextMenu',root.menu);

set(handles.axPreview,'xlim',dx);

set(handles.axPreview,'ylim',dy);

axis(handles.axPreview,'off');

hold(handles.axPreview,'off');

% --------------------------------------------------------------------

function [width, height]=getwindowsize(fig)

oldunits = get(fig, 'Units');

set(fig, 'Units', 'pixels');

figpos = get(fig, 'Position');

set(fig, 'Units', oldunits);

width=figpos(3);

height=figpos(4);

function [hg,hobj]=updategraph(root, handles)

set(handles.fgI2M,'userdata',root);

hg=plot(root.graph,'parent',handles.axFlow,'ArrowSize',15);

hobj=updatepreview(root,hg,handles);

% set(hg,'Selected','on');

axis(handles.axFlow,'off');

set(handles.axFlow,'XColor','none')

set(hg,'UIContextMenu',root.menu);

% --------------------------------------------------------------------

function miEllipsoid_Callback(hObject, eventdata, handles)

prompt = {'Center (1x3 vector):',...

'Radii (a scalar, or 1x3 or 1x5 vector):',...

'Max element volume (scalar, 0 - only create surface):',...

'Circle division:'};

title = 'Create an Ellipsoid Mesh';

dims = [1 1 1 1];

definput = {'[0 0 0]','[50 30 20]','3','30'};

res = inputdlg(prompt,title,dims,definput);

if(isempty(res))

return;

end

newtype=dummytype;

opt=str2num(res{3});

maxvol=str2num(res{4});

if(maxvol==0)

[newdata.node,newdata.face]=meshanellip(eval(res{1}),eval(res{2}),opt);

else

[newdata.node,newdata.face,newdata.elem]=meshanellip(eval(res{1}),...

eval(res{2}),opt, maxvol);

newtype.haselem=1;

end

newtype.hasnode=1;

newtype.hasface=1;

if(exist('newdata','var') && exist('newtype','var'))

newkey=addnodewithdata(handles,newdata,newtype,'Cyl');

end

% --------------------------------------------------------------------

function miLattice_Callback(hObject, eventdata, handles)

prompt = {'X-lattice range (a vector):',...

'Y-lattice range (a vector):',...

'Z-lattice range (a vector):',...

'Max element volume (scalar, 0 - only create surface):'};

title = 'Create Lattice Grid Mesh';

dims = [1 1 1 1];

definput = {'[1 100]','[1 50]','[1 10 30]','30'};

res = inputdlg(prompt,title,dims,definput);

if(isempty(res))

return;

end

newtype=dummytype;

maxvol=str2num(res{4});

if(maxvol==0)

[newdata.node,newdata.face]=latticegrid(eval(res{1}),eval(res{2}),eval(res{3}));

else

[no,fc,c0]=latticegrid(eval(res{1}),eval(res{2}),eval(res{3}));

[newdata.node,newdata.elem,newdata.face]=surf2mesh(no,fc,[],[],1,maxvol,c0);

newtype.haselem=1;

end

newtype.hasnode=1;

newtype.hasface=1;

if(exist('newdata','var') && exist('newtype','var'))

newkey=addnodewithdata(handles,newdata,newtype,'Lattice');

end

% --------------------------------------------------------------------

function miMeshgrid5_Callback(hObject, eventdata, handles)

prompt = {'X-lattice range (a vector):',...

'Y-lattice range (a vector):',...

'Z-lattice range (a vector):'};

title = 'Create Meshgrid (5 tet/cell) Mesh';

dims = [1 1 1];

definput = {'1:10','1:8','1:5'};

res = inputdlg(prompt,title,dims,definput);

if(isempty(res))

return;

end

newtype=dummytype;

[newdata.node,newdata.elem]=meshgrid5(eval(res{1}),eval(res{2}),eval(res{3}));

newdata.face=volface(newdata.elem);

newtype.hasnode=1;

newtype.hasface=1;

newtype.haselem=1;

if(exist('newdata','var') && exist('newtype','var'))

newkey=addnodewithdata(handles,newdata,newtype,'Meshgrid5_');

end

% --------------------------------------------------------------------

function miMeshgrid6_Callback(hObject, eventdata, handles)

prompt = {'X-lattice range (a vector):',...

'Y-lattice range (a vector):',...

'Z-lattice range (a vector):'};

title = 'Create Meshgrid (6 tet/cell) Mesh';

dims = [1 1 1];

definput = {'1:10','1:8','1:5'};

res = inputdlg(prompt,title,dims,definput);

if(isempty(res))

return;

end

newtype=dummytype;

[newdata.node,newdata.elem]=meshgrid5(eval(res{1}),eval(res{2}),eval(res{3}));

newdata.face=volface(newdata.elem);

newtype.hasnode=1;

newtype.hasface=1;

newtype.haselem=1;

if(exist('newdata','var') && exist('newtype','var'))

newkey=addnodewithdata(handles,newdata,newtype,'Meshgrid6_');

end

% --------------------------------------------------------------------

function miOpen_Callback(hObject, eventdata, handles)

filter = {'*.mat';'*.*'};

root=get(handles.fgI2M,'userdata');

[file, path] = uigetfile(filter,'Load workspace');

if isequal(file,0)

return;

else

data=load(fullfile(path,file));

end

if(isfield(data,'i2mworkspace'))

root.graph=data.i2mworkspace;

updategraph(root,handles);

else

warndlg('no saved workspace found','Warning');

end

% --------------------------------------------------------------------

function miSaveAll_Callback(hObject, eventdata, handles)

root=get(handles.fgI2M,'userdata');

i2mworkspace=root.graph;

filter = {'*.mat';'*.*'};

[file, path] = uiputfile(filter,'Save workspace');

if ~isequal(file,0) && ~isequal(path,0)

save(fullfile(path,file),'i2mworkspace');

end

% --------------------------------------------------------------------

function miLoadVar_Callback(hObject, eventdata, handles)

nodedata=struct;

[file,path] = uigetfile({'*.mat','MATLAB data (*.mat)'});

if isequal(file,0)

return;

else

data=load(fullfile(path,file));

vars=fieldnames(data);

[idx, isok]=listdlg('ListString',vars,...

'PromptString','Select a 3D array:');

if(~isok)

return;

end

for i=1:length(idx)

dat=data.(vars{idx(i)});

if(ndims(dat)==3 && ~isfield(nodedata,'vol'))

nodedata.vol=dat;

else

nodedata.(vars{idx(i)})=dat;

end

end

end

adddatatograph(handles,nodedata);

% --------------------------------------------------------------------

function miExit_Callback(hObject, eventdata, handles)

close(handles.fgI2M);

% --------------------------------------------------------------------

function miRefresh_Callback(hObject, eventdata, handles)

root=get(handles.fgI2M,'userdata');

updategraph(root, handles);

一键复制

编辑

Web IDE

原始数据

按行查看

历史

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值