From 2bf959c546e8b8eb1df8dad022631be4d25f7e6c Mon Sep 17 00:00:00 2001 From: Qianqian Fang Date: Sun, 27 Oct 2024 22:15:12 -0400 Subject: [PATCH] [gui] add try/except for meshing tasks,pgup/pgdown to slice z --- i2m.png | Bin 49701 -> 79487 bytes i2m.prj | 9 +- img2mesh.m | 320 ++++++++++++++++++++++++++++++----------------------- 3 files changed, 185 insertions(+), 144 deletions(-) diff --git a/i2m.png b/i2m.png index 68441dba2799735c7aadae9798b2fbf6653d0892..a403761e114328f6b18d792e725095b2ce4b22a0 100644 GIT binary patch delta 30105 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 z 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 delta 86 zcmezWhGl6B^8{r!rh@@KA+DR-OAa!z9KHO>da_Tsh4CW}HYRhUo8pS^7#J92GeaUu qobz*YQ}arITm}Z`qSVBa)D(sC%#sWRcTeAd6ungT&6~^5>;nK~)gIvh diff --git a/i2m.prj b/i2m.prj index b0eac45..c4a08a2 100644 --- a/i2m.prj +++ b/i2m.prj @@ -1,7 +1,7 @@ i2m - + ${PROJECT_ROOT}/i2m.png 0.9 Qianqian Fang @@ -9,10 +9,10 @@ Northeastern University I2M is an integrated graphical user interface (GUI) for the 3D meshing toolbox Iso2Mesh developed by Qianqian Fang Iso2Mesh is a free matlab/octave-based mesh generation and processing toolbox. It can create 3D tetrahedral finite element (FE) mesh from surfaces, 3D binary and gray-scale volumetric images such as segmented MRI/CT scans. - + ${PROJECT_ROOT}/i2m.png - /local/i2m/ - option.installpath.user + iso2mesh/i2m/ + option.installpath.appdata ${PROJECT_ROOT}/i2m.png In the following directions, replace MCR_ROOT by the directory where the MATLAB Runtime is installed on the target machine. @@ -158,7 +158,6 @@ ${PROJECT_ROOT}/smoothsurf.m ${PROJECT_ROOT}/sms.m ${PROJECT_ROOT}/sortmesh.m - ${PROJECT_ROOT}/struct2jdata.m ${PROJECT_ROOT}/surf2mesh.m ${PROJECT_ROOT}/surf2vol.m ${PROJECT_ROOT}/surf2volz.m diff --git a/img2mesh.m b/img2mesh.m index 67b4809..9fdb701 100644 --- a/img2mesh.m +++ b/img2mesh.m @@ -69,7 +69,6 @@ function i2m_OpeningFcn(hObject, eventdata, handles, varargin) 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'); @@ -94,7 +93,7 @@ function i2m_OpeningFcn(hObject, eventdata, handles, varargin) mirefresh.Separator = 'on'; hbackground = axes('units', 'normalized', 'position', [0 0 1 1]); -uistack(hbackground, 'down'); +uistack(hbackground, 'bottom'); text(0.97, 0, 'Iso2Mesh', 'FontSize', 40, 'Color', [1 1 1], 'Parent', hbackground, ... 'HorizontalAlignment', 'right', 'VerticalAlignment', 'bottom', ... 'FontWeight', 'bold', 'FontName', 'sans', 'FontAngle', 'italic'); @@ -340,14 +339,14 @@ function processdata(source, callbackdata, handles) 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)); + figure('keypressfcn', @plotfigevent, 'name', 'Shortcut:left/right:crop Y;up/down:crop X;pgup/pgdown:crop Z', '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)); + figure('keypressfcn', @plotfigevent, 'name', 'Shortcut:left/right:crop Y;up/down:crop X;pgup/pgdown:crop Z', 'userdata', struct('node', nodedata.node, 'elem', [], 'face', nodedata.face)); plotmesh(nodedata.node, nodedata.face); end else - figure('keypressfcn', @plotfigevent, 'userdata', struct('vol', nodedata.vol)); + figure('keypressfcn', @plotfigevent, 'name', 'Shortcut:left/right:crop Y;up/down:crop X;pgup/pgdown:crop Z', '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 @@ -400,7 +399,7 @@ function processdata(source, callbackdata, handles) if (~nodetype.haselem && ~nodetype.hasnode) errordlg('selected data does not have a mesh'); end - filter = {'*.jmsh'; '*.*'}; + filter = {'*.bmsh'; '*.jmsh'; '*.*'}; [file, path] = uiputfile(filter, 'Export mesh'); if ~isequal(file, 0) && ~isequal(path, 0) if (nodetype.haselem) @@ -440,6 +439,8 @@ function plotfigevent(hobject, event) end if (isempty(plotpos)) switch event.Key + case {'pageup', 'pagedown'} + plotpos = 9; case {'rightarrow', 'uparrow'} plotpos = 0; case {'leftarrow', 'downarrow'} @@ -464,6 +465,12 @@ function plotfigevent(hobject, event) 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))); + case 'pageup' + plotpos = min(plotpos + 1, 10); + plotmesh(data.node, data.face, data.elem, sprintf('z<%f', (pmax(3) - pmin(3)) * plotpos * 0.1 + pmin(3))); + case 'pagedown' + plotpos = max(plotpos - 1, 1); + plotmesh(data.node, data.face, data.elem, sprintf('z<%f', (pmax(3) - pmin(3)) * plotpos * 0.1 + pmin(3))); otherwise end end @@ -501,12 +508,16 @@ function plotfigevent(hobject, event) end opt = struct('radbound', str2double(res{2}), 'distbound', str2double(res{3})); -[newdata.node, newdata.face] = v2s(data.vol, eval(res{1}), opt, res{4}); +try + [newdata.node, newdata.face] = v2s(data.vol, eval(res{1}), opt, res{4}); +catch err + errdlg(err.message, 'v2sgui'); +end newtype.hasnode = 1; newtype.hasface = 1; % ---------------------------------------------------------------- -function [newdata, newtype] = v2mgui(data) +function [newdata, newtype] = v2mgui(data, varargin) prompt = {'Threshold (scalar or []):', ... 'Surface element radius bound (scalar):', ... 'Surface element distance bound (scalar)', ... @@ -523,8 +534,13 @@ function plotfigevent(hobject, event) end opt = struct('radbound', str2double(res{2}), 'distbound', str2double(res{3})); -[newdata.node, newdata.elem, newdata.face] = v2m(data.vol, eval(res{1}), ... - opt, res{4}); + +try + [newdata.node, newdata.elem, newdata.face] = v2m(data.vol, eval(res{1}), ... + opt, res{4}, varargin{:}); +catch err + errdlg(err.message, 'v2mgui'); +end newtype.hasnode = 1; newtype.hasface = 1; newtype.haselem = 1; @@ -567,10 +583,13 @@ function plotfigevent(hobject, event) if (isempty(res)) return end - -[newdata.node, newdata.elem, newdata.face] = ... - s2m(data.node, data.face, str2double(res{1}), ... - str2double(res{2}), res{3}, eval(res{4}), eval(res{5})); +try + [newdata.node, newdata.elem, newdata.face] = ... + s2m(data.node, data.face, str2double(res{1}), ... + str2double(res{2}), res{3}, eval(res{4}), eval(res{5})); +catch err + errdlg(err.message, 's2mgui'); +end newtype.hasnode = 1; newtype.hasface = 1; newtype.haselem = 1; @@ -628,13 +647,17 @@ function miSphere_Callback(hObject, eventdata, handles) end newtype = dummytype; opt = str2double(res{3}); -if (str2double(res{4}) == 0) - [newdata.node, newdata.face] = meshasphere(eval(res{1}), ... - str2double(res{2}), opt); -else - [newdata.node, newdata.face, newdata.elem] = meshasphere(eval(res{1}), ... - str2double(res{2}), opt, str2double(res{4})); - newtype.haselem = 1; +try + if (str2double(res{4}) == 0) + [newdata.node, newdata.face] = meshasphere(eval(res{1}), ... + str2double(res{2}), opt); + else + [newdata.node, newdata.face, newdata.elem] = meshasphere(eval(res{1}), ... + str2double(res{2}), opt, str2double(res{4})); + newtype.haselem = 1; + end +catch err + errdlg(err.message, 'meshasphere'); end newtype.hasnode = 1; newtype.hasface = 1; @@ -657,13 +680,18 @@ function miBox_Callback(hObject, eventdata, handles) end newtype = dummytype; opt = str2double(res{3}); -if (str2double(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, str2double(res{4})); - newtype.haselem = 1; +try + if (str2double(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, str2double(res{4})); + newtype.haselem = 1; + end +catch err + errdlg(err.message, 'meshabox'); end + newtype.hasnode = 1; newtype.hasface = 1; @@ -687,14 +715,17 @@ function miCylinder_Callback(hObject, eventdata, handles) newtype = dummytype; opt = str2double(res{4}); maxvol = str2double(res{5}); - -if (maxvol == 0) - [newdata.node, newdata.face] = meshacylinder(eval(res{1}), eval(res{2}), ... - str2double(res{3}), opt); -else - [newdata.node, newdata.face, newdata.elem] = meshacylinder(eval(res{1}), eval(res{2}), ... - str2double(res{3}), opt, maxvol); - newtype.haselem = 1; +try + if (maxvol == 0) + [newdata.node, newdata.face] = meshacylinder(eval(res{1}), eval(res{2}), ... + str2double(res{3}), opt); + else + [newdata.node, newdata.face, newdata.elem] = meshacylinder(eval(res{1}), eval(res{2}), ... + str2double(res{3}), opt, maxvol); + newtype.haselem = 1; + end +catch err + errdlg(err.message, 'meshacylinder'); end newtype.hasnode = 1; newtype.hasface = 1; @@ -705,63 +736,66 @@ function miCylinder_Callback(hObject, eventdata, handles) % -------------------------------------------------------------------- function miLoadVol_Callback(hObject, eventdata, handles) - -nodedata = struct; -nodetype = dummytype; -filters = {'*.jnii;*.nii;*.hdr;*.img;*.tif;*.tiff;*.inr;*.bin;*.ubj', '3D volume file (*.jnii;*.nii;*.hdr;*.img;*.tif;*.tiff;*.inr;*.bin;*.ubj)'; ... - '*.jnii', 'JNIFTI file (*.jnii)'; ... - '*.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)'; ... - '*.jdb', 'Binary JSON (*.jdb)'; ... - '*.*', 'All (*.*)'}; -[file, path] = uigetfile(filters); -if isequal(file, 0) - return -else - if (~isempty(regexpi(file, '\.j*nii(\.gz)*$', 'once'))) - im = loadnifti(fullfile(path, file)); - if (isfield(im, 'NIFTIData')) - nodedata.vol = im.NIFTIData; - else +try + nodedata = struct; + nodetype = dummytype; + filters = {'*.jnii;*.nii;*.hdr;*.img;*.tif;*.tiff;*.inr;*.bin;*.ubj', '3D volume file (*.jnii;*.nii;*.hdr;*.img;*.tif;*.tiff;*.inr;*.bin;*.ubj)'; ... + '*.jnii', 'JNIFTI file (*.jnii)'; ... + '*.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)'; ... + '*.jdb', 'Binary JSON (*.jdb)'; ... + '*.*', 'All (*.*)'}; + [file, path] = uigetfile(filters); + if isequal(file, 0) + return + else + if (~isempty(regexpi(file, '\.j*nii(\.gz)*$', 'once'))) + im = loadnifti(fullfile(path, file)); + if (isfield(im, 'NIFTIData')) + nodedata.vol = im.NIFTIData; + else + nodedata.vol = im.img; + end + nodetype.hasvol = 1; + elseif (~isempty(regexpi(file, '(\.hdr$|\.[img$)', 'once'))) + im = loadnifti(fullfile(path, file)); nodedata.vol = im.img; - end - nodetype.hasvol = 1; - elseif (~isempty(regexpi(file, '(\.hdr$|\.[img$)', 'once'))) - im = loadnifti(fullfile(path, file)); - nodedata.vol = im.img; - nodetype.hasvol = 1; - elseif (~isempty(regexpi(file, '\.tiff*$', 'once'))) - nodedata.vol = readmptiff(fullfile(path, file)); - nodetype.hasvol = 1; - elseif (~isempty(regexpi(file, '\.inr$', 'once'))) - nodedata.vol = readinr(fullfile(path, file)); - nodetype.hasvol = 1; - elseif (~isempty(regexpi(file, '\.bin$', 'once'))) - 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 - fid = fopen(fullfile(path, file), 'rb'); - if (fid == 0) - errordlg('can not open the specified file'); - end - nodedata.vol = fread(fid, eval(res{1}), res{2}); - fclose(fid); - nodetype.hasvol = 1; - elseif (~isempty(regexpi(file, '\.jdb$', 'once'))) - nodedata = loadjd(fullfile(path, file)); - if (isstruct(nodedata) && isfield(nodedata, 'vol')) nodetype.hasvol = 1; + elseif (~isempty(regexpi(file, '\.tiff*$', 'once'))) + nodedata.vol = readmptiff(fullfile(path, file)); + nodetype.hasvol = 1; + elseif (~isempty(regexpi(file, '\.inr$', 'once'))) + nodedata.vol = readinr(fullfile(path, file)); + nodetype.hasvol = 1; + elseif (~isempty(regexpi(file, '\.bin$', 'once'))) + 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 + fid = fopen(fullfile(path, file), 'rb'); + if (fid == 0) + errordlg('can not open the specified file'); + end + nodedata.vol = fread(fid, eval(res{1}), res{2}); + fclose(fid); + nodetype.hasvol = 1; + elseif (~isempty(regexpi(file, '\.jdb$', 'once'))) + nodedata = loadjd(fullfile(path, file)); + if (isstruct(nodedata) && isfield(nodedata, 'vol')) + nodetype.hasvol = 1; + end end end +catch err + errdlg(err.message, 'LoadVol'); end if (exist('nodedata', 'var')) @@ -775,33 +809,37 @@ function miLoadVol_Callback(hObject, eventdata, handles) % -------------------------------------------------------------------- function miLoadMesh_Callback(hObject, eventdata, handles) - -nodedata = struct; -nodetype = dummytype; -filters = {'*.jmsh;*.bmsh,*.off;*.medit;*.smf;*.json', '3D Mesh files (*.jmsh;*.bmsh;*.off;*.medit;*.smf;*.json)'; ... - '*.jmsh', 'JSON mesh (*.jmsh)'; ... - '*.bmsh', 'Binary JSON mesh (*.bmsh)'; ... - '*.off', 'OFF file (*.off)'; ... - '*.medit', 'Medit file (*.medit)'; ... - '*.ele', 'Tetgen element mesh file (*.ele)'; ... - '*.json', 'JSON file (*.json)'; '*.*', 'All (*.*)'}; -[file, path] = uigetfile(filters); -if isequal(file, 0) - return -else - if (~isempty(regexpi(file, '\.off$', 'once'))) - [nodedata.node, nodedata.face] = readoff(fullfile(path, file)); - elseif (~isempty(regexpi(file, '\.medit$', 'once'))) - [nodedata.node, nodedata.elem] = readmedit(fullfile(path, file)); - elseif (~isempty(regexpi(file, '\.ele$', 'once'))) - [pathstr, name] = fileparts(fullfile(path, file)); - [nodedata.node, nodedata.elem] = readtetgen(fullfile(pathstr, name)); - elseif (~isempty(regexpi(file, '\.[bj]me*sh$', 'once'))) - nodedata = importjmesh(fullfile(path, file)); - elseif (~isempty(regexpi(file, '\.json$', 'once'))) - nodedata = loadjd(fullfile(path, file)); +try + nodedata = struct; + nodetype = dummytype; + filters = {'*.jmsh;*.bmsh,*.off;*.medit;*.smf;*.json', '3D Mesh files (*.jmsh;*.bmsh;*.off;*.medit;*.smf;*.json)'; ... + '*.jmsh', 'JSON mesh (*.jmsh)'; ... + '*.bmsh', 'Binary JSON mesh (*.bmsh)'; ... + '*.off', 'OFF file (*.off)'; ... + '*.medit', 'Medit file (*.medit)'; ... + '*.ele', 'Tetgen element mesh file (*.ele)'; ... + '*.json', 'JSON file (*.json)'; '*.*', 'All (*.*)'}; + [file, path] = uigetfile(filters); + if isequal(file, 0) + return + else + if (~isempty(regexpi(file, '\.off$', 'once'))) + [nodedata.node, nodedata.face] = readoff(fullfile(path, file)); + elseif (~isempty(regexpi(file, '\.medit$', 'once'))) + [nodedata.node, nodedata.elem] = readmedit(fullfile(path, file)); + elseif (~isempty(regexpi(file, '\.ele$', 'once'))) + [pathstr, name] = fileparts(fullfile(path, file)); + [nodedata.node, nodedata.elem] = readtetgen(fullfile(pathstr, name)); + elseif (~isempty(regexpi(file, '\.[bj]me*sh$', 'once'))) + nodedata = importjmesh(fullfile(path, file)); + elseif (~isempty(regexpi(file, '\.json$', 'once'))) + nodedata = loadjd(fullfile(path, file)); + end end +catch err + errdlg(err.message, 'LoadMesh'); end + if (exist('nodedata', 'var')) adddatatograph(handles, nodedata); else @@ -810,33 +848,37 @@ function miLoadMesh_Callback(hObject, eventdata, handles) % -------------------------------------------------------------------- function miLoadSurf_Callback(hObject, eventdata, handles) -nodedata = struct; -nodetype = dummytype; -filters = {'*.jmsh;*.bmsh;*.off;*.asc;*.smf;*.smf;*.json', '3D Mesh files (*.jmsh;*.bmsh;*.off;*.asc;*.smf;*.smf;*.json)'; ... - '*.jmsh', 'JSON mesh (*.jmsh)'; ... - '*.bmsh', 'Binary JSON mesh (*.bmsh)'; ... - '*.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] = uigetfile(filters); -if isequal(file, 0) - return -else - if (~isempty(regexpi(file, '\.off$', 'once'))) - [nodedata.node, nodedata.face] = readoff(fullfile(path, file)); - elseif (~isempty(regexpi(file, '\.asc$', 'once'))) - [nodedata.node, nodedata.face] = readasc(fullfile(path, file)); - elseif (~isempty(regexpi(file, '\.gts$', 'once'))) - [nodedata.node, nodedata.face] = readgts(fullfile(path, file)); - elseif (~isempty(regexpi(file, '\.smf$', 'once'))) - [nodedata.node, nodedata.face] = readsmf(fullfile(path, file)); - elseif (~isempty(regexpi(file, '\.[bj]me*sh$', 'once'))) - nodedata = importjmesh(fullfile(path, file)); - elseif (~isempty(regexpi(file, '\.json$', 'once'))) - nodedata = loadjd(fullfile(path, file)); +try + nodedata = struct; + nodetype = dummytype; + filters = {'*.jmsh;*.bmsh;*.off;*.asc;*.smf;*.smf;*.json', '3D Mesh files (*.jmsh;*.bmsh;*.off;*.asc;*.smf;*.smf;*.json)'; ... + '*.jmsh', 'JSON mesh (*.jmsh)'; ... + '*.bmsh', 'Binary JSON mesh (*.bmsh)'; ... + '*.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] = uigetfile(filters); + if isequal(file, 0) + return + else + if (~isempty(regexpi(file, '\.off$', 'once'))) + [nodedata.node, nodedata.face] = readoff(fullfile(path, file)); + elseif (~isempty(regexpi(file, '\.asc$', 'once'))) + [nodedata.node, nodedata.face] = readasc(fullfile(path, file)); + elseif (~isempty(regexpi(file, '\.gts$', 'once'))) + [nodedata.node, nodedata.face] = readgts(fullfile(path, file)); + elseif (~isempty(regexpi(file, '\.smf$', 'once'))) + [nodedata.node, nodedata.face] = readsmf(fullfile(path, file)); + elseif (~isempty(regexpi(file, '\.[bj]me*sh$', 'once'))) + nodedata = importjmesh(fullfile(path, file)); + elseif (~isempty(regexpi(file, '\.json$', 'once'))) + nodedata = loadjd(fullfile(path, file)); + end end +catch err + errdlg(err.message, 'LoadSurf'); end if (exist('nodedata', 'var')) adddatatograph(handles, nodedata);