diff --git a/ShoulderCase/@ShoulderCasePlotter/ShoulderCasePlotter.m b/ShoulderCase/@ShoulderCasePlotter/ShoulderCasePlotter.m new file mode 100644 index 0000000..44fb4c6 --- /dev/null +++ b/ShoulderCase/@ShoulderCasePlotter/ShoulderCasePlotter.m @@ -0,0 +1,53 @@ +classdef ShoulderCasePlotter < handle +% Create a figure with ShoulderCase's plots +% and buttons to toggle the data visualisation. +% +% Used by the ShoulderCase.plot() method. + + properties (Access = private) + SCase + fig + axesHandle + plotHandle + buttonHandle + options = {'wireframe',... + 'scapula surface',... + 'glenoid',... + 'coordinate system',... + 'centered coordinate system',... + 'rotator cuff',... + 'difference'}; + end + + + + methods (Access = ?ShoulderCase) + + function obj = ShoulderCasePlotter(SCase) + obj.SCase = SCase; + obj.fig = figure('Name',SCase.id,... + 'NumberTitle','off',... + 'units','normalized',... + 'outerposition',[0 0 1 1]); + obj.axesHandle = containers.Map; + obj.plotHandle = {}; + obj.buttonHandle = {}; + + obj.initializeLayout(); + obj.plot(); + obj.initializeButton(); + end + + end + + + + methods (Access = private) + + initializeButton(obj); + initializeLayout(obj); + plot(obj); + + end + +end \ No newline at end of file diff --git a/ShoulderCase/@ShoulderCasePlotter/initializeButton.m b/ShoulderCase/@ShoulderCasePlotter/initializeButton.m new file mode 100644 index 0000000..2963299 --- /dev/null +++ b/ShoulderCase/@ShoulderCasePlotter/initializeButton.m @@ -0,0 +1,48 @@ +function initializeButton(obj) + autoPanel = uipanel(obj.fig,... + 'Title','Auto',... + 'units','pixels',... + 'Position',[10 320 180 150 ]); + for i = 1:length(obj.options)-1 + try + obj.buttonHandle.auto(i) = uicontrol(autoPanel,... + 'Style','checkbox',... + 'Value',1,... + 'String',obj.options{i},... + 'position',[10,130-i*20,150,20],... + 'Callback',{@setDataVisibility,obj.plotHandle.auto(obj.options{i})}); + end + end + + manualPanel = uipanel(obj.fig,... + 'Title','Manual',... + 'units','pixels',... + 'Position',[10 160 180 150 ]); + for i = 1:length(obj.options)-1 + try + obj.buttonHandle.manual(i) = uicontrol(manualPanel,... + 'Style','checkbox',... + 'Value',1,... + 'String',obj.options{i},... + 'position',[10,130-i*20,150,20],... + 'Callback',{@setDataVisibility,obj.plotHandle.manual(obj.options{i})}); + end + end + + try + obj.buttonHandle.difference = uicontrol(obj.fig,... + 'Style','checkbox',... + 'Value',1,... + 'String','auto/manual difference',... + 'position',[20,130,150,20],... + 'Callback',{@setDataVisibility,obj.plotHandle.difference('difference')}); + end +end + +function setDataVisibility(button,event,dataHandle) + + for i = 1:length(dataHandle) + set(dataHandle(i),'Visible',logical(button.Value)); + end + +end \ No newline at end of file diff --git a/ShoulderCase/@ShoulderCasePlotter/initializeLayout.m b/ShoulderCase/@ShoulderCasePlotter/initializeLayout.m new file mode 100644 index 0000000..a95c7f5 --- /dev/null +++ b/ShoulderCase/@ShoulderCasePlotter/initializeLayout.m @@ -0,0 +1,6 @@ +function initializeLayout(obj) + obj.axesHandle('scapula') = subplot(2,4,[1 2 5 6]); + obj.axesHandle('centered coordinate system') = subplot(2,4,[3 4]); + obj.axesHandle('manual muscles') = subplot(2,4,7); + obj.axesHandle('auto muscles') = subplot(2,4,8); +end \ No newline at end of file diff --git a/ShoulderCase/@ShoulderCasePlotter/plot.m b/ShoulderCase/@ShoulderCasePlotter/plot.m new file mode 100644 index 0000000..c3d0501 --- /dev/null +++ b/ShoulderCase/@ShoulderCasePlotter/plot.m @@ -0,0 +1,91 @@ +function plot(obj) + % set method colors + autoColors = {'b','#D9FFFF'}; + manualColors = {'#D95319','#FFFF00'}; + + + + % plot scapula data + axes(obj.axesHandle('scapula')); + title('Auto is blue, manual is red'); + hold on; + grid on + axis vis3d + rotate3d on + + auto = containers.Map; + try + auto('wireframe') = obj.SCase.shoulderAuto.scapula.plotLandmarksWireframe(autoColors{1},autoColors{2}); + end + try + auto('scapula surface') = obj.SCase.shoulderAuto.scapula.plotSurface(autoColors{1},autoColors{2}); + end + try + auto('glenoid') = obj.SCase.shoulderAuto.scapula.glenoid.plot(); + end + try + auto('coordinate system') = obj.SCase.shoulderAuto.scapula.coordSys.plot(autoColors{1},false); + end + + manual = containers.Map; + try + manual('wireframe') = obj.SCase.shoulderManual.scapula.plotLandmarksWireframe(manualColors{1},manualColors{2}); + end + try + manual('scapula surface') = obj.SCase.shoulderManual.scapula.plotSurface(manualColors{1},manualColors{2}); + end + try + manual('glenoid') = obj.SCase.shoulderManual.scapula.glenoid.plot(); + end + try + manual('coordinate system') = obj.SCase.shoulderManual.scapula.coordSys.plot(manualColors{1},false); + end + + outliersNormLimit = 10; + difference = containers.Map; + try + difference('difference') = obj.SCase.plotManualAutoDifferences(outliersNormLimit); + end + + + + % plot coordinateSystem data + axes(obj.axesHandle('centered coordinate system')); + title('Auto is blue, manual is red'); + hold on; + grid on + axis vis3d + rotate3d on + + try + auto('centered coordinate system') = obj.SCase.shoulderAuto.scapula.coordSys.plot(autoColors{1},true); + end + try + manual('centered coordinate system') = obj.SCase.shoulderManual.scapula.coordSys.plot(manualColors{1},true); + end + + + + % plot muscles segmentation + axes(obj.axesHandle('auto muscles')); + title('Auto'); + hold on; + + try + auto('rotator cuff') = obj.SCase.shoulderAuto.muscles.plot(); + end + + axes(obj.axesHandle('manual muscles')); + title('Manual'); + hold on; + + try + manual('rotator cuff') = obj.SCase.shoulderManual.muscles.plot(); + end + + + % store the data handles + obj.plotHandle.auto = auto; + obj.plotHandle.manual = manual; + obj.plotHandle.difference = difference; +end