Commit 1aea71561f1f115abf940dc090e97767ce9d4ff5

Authored by Thiago Franco de Moraes
1 parent 5cc84dd2
Exists in ff_mask

Undo and Redo

invesalius/constants.py
@@ -538,7 +538,7 @@ STYLE_LEVEL = {SLICE_STATE_EDITOR: 1, @@ -538,7 +538,7 @@ STYLE_LEVEL = {SLICE_STATE_EDITOR: 1,
538 STATE_DEFAULT: 0, 538 STATE_DEFAULT: 0,
539 STATE_MEASURE_ANGLE: 2, 539 STATE_MEASURE_ANGLE: 2,
540 STATE_MEASURE_DISTANCE: 2, 540 STATE_MEASURE_DISTANCE: 2,
541 - STATE_WL: 2, 541 + STATE_WL: 3,
542 STATE_SPIN: 2, 542 STATE_SPIN: 2,
543 STATE_ZOOM: 2, 543 STATE_ZOOM: 2,
544 STATE_ZOOM_SL: 2, 544 STATE_ZOOM_SL: 2,
invesalius/data/mask.py
@@ -60,6 +60,8 @@ class EditionHistoryNode(object): @@ -60,6 +60,8 @@ class EditionHistoryNode(object):
60 mvolume[1:, 1:, self.index+1] = array 60 mvolume[1:, 1:, self.index+1] = array
61 if self.clean: 61 if self.clean:
62 mvolume[0, 0, self.index+1] = 1 62 mvolume[0, 0, self.index+1] = 1
  63 + elif self.orientation == 'VOLUME':
  64 + mvolume[:] = array
63 65
64 print "applying to", self.orientation, "at slice", self.index 66 print "applying to", self.orientation, "at slice", self.index
65 67
@@ -106,7 +108,15 @@ class EditionHistory(object): @@ -106,7 +108,15 @@ class EditionHistory(object):
106 ##self.index -= 1 108 ##self.index -= 1
107 ##h[self.index].commit_history(mvolume) 109 ##h[self.index].commit_history(mvolume)
108 #self._reload_slice(self.index - 1) 110 #self._reload_slice(self.index - 1)
109 - if actual_slices and actual_slices[h[self.index - 1].orientation] != h[self.index - 1].index: 111 + if h[self.index - 1].orientation == 'VOLUME':
  112 + self.index -= 1
  113 + print "================================"
  114 + print mvolume.shape
  115 + print "================================"
  116 + h[self.index].commit_history(mvolume)
  117 + self._reload_slice(self.index)
  118 + Publisher.sendMessage("Enable redo", True)
  119 + elif actual_slices and actual_slices[h[self.index - 1].orientation] != h[self.index - 1].index:
110 self._reload_slice(self.index - 1) 120 self._reload_slice(self.index - 1)
111 else: 121 else:
112 self.index -= 1 122 self.index -= 1
@@ -129,7 +139,12 @@ class EditionHistory(object): @@ -129,7 +139,12 @@ class EditionHistory(object):
129 ##h[self.index].commit_history(mvolume) 139 ##h[self.index].commit_history(mvolume)
130 #self._reload_slice(self.index + 1) 140 #self._reload_slice(self.index + 1)
131 141
132 - if actual_slices and actual_slices[h[self.index + 1].orientation] != h[self.index + 1].index: 142 + if h[self.index + 1].orientation == 'VOLUME':
  143 + self.index += 1
  144 + h[self.index].commit_history(mvolume)
  145 + self._reload_slice(self.index)
  146 + Publisher.sendMessage("Enable undo", True)
  147 + elif actual_slices and actual_slices[h[self.index + 1].orientation] != h[self.index + 1].index:
133 self._reload_slice(self.index + 1) 148 self._reload_slice(self.index + 1)
134 else: 149 else:
135 self.index += 1 150 self.index += 1
invesalius/data/slice_.py
@@ -1402,7 +1402,8 @@ class Slice(object): @@ -1402,7 +1402,8 @@ class Slice(object):
1402 buffer_slices = self.buffer_slices 1402 buffer_slices = self.buffer_slices
1403 actual_slices = {"AXIAL": buffer_slices["AXIAL"].index, 1403 actual_slices = {"AXIAL": buffer_slices["AXIAL"].index,
1404 "CORONAL": buffer_slices["CORONAL"].index, 1404 "CORONAL": buffer_slices["CORONAL"].index,
1405 - "SAGITAL": buffer_slices["SAGITAL"].index,} 1405 + "SAGITAL": buffer_slices["SAGITAL"].index,
  1406 + "VOLUME": 0}
1406 self.current_mask.undo_history(actual_slices) 1407 self.current_mask.undo_history(actual_slices)
1407 for o in self.buffer_slices: 1408 for o in self.buffer_slices:
1408 self.buffer_slices[o].discard_mask() 1409 self.buffer_slices[o].discard_mask()
@@ -1413,7 +1414,8 @@ class Slice(object): @@ -1413,7 +1414,8 @@ class Slice(object):
1413 buffer_slices = self.buffer_slices 1414 buffer_slices = self.buffer_slices
1414 actual_slices = {"AXIAL": buffer_slices["AXIAL"].index, 1415 actual_slices = {"AXIAL": buffer_slices["AXIAL"].index,
1415 "CORONAL": buffer_slices["CORONAL"].index, 1416 "CORONAL": buffer_slices["CORONAL"].index,
1416 - "SAGITAL": buffer_slices["SAGITAL"].index,} 1417 + "SAGITAL": buffer_slices["SAGITAL"].index,
  1418 + "VOLUME": 0}
1417 self.current_mask.redo_history(actual_slices) 1419 self.current_mask.redo_history(actual_slices)
1418 for o in self.buffer_slices: 1420 for o in self.buffer_slices:
1419 self.buffer_slices[o].discard_mask() 1421 self.buffer_slices[o].discard_mask()
invesalius/data/styles.py
@@ -1814,11 +1814,15 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle): @@ -1814,11 +1814,15 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle):
1814 if position < 0: 1814 if position < 0:
1815 position = viewer.calculate_matrix_position(coord) 1815 position = viewer.calculate_matrix_position(coord)
1816 1816
  1817 + mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:]
1817 x, y, z = self.calcultate_scroll_position(position) 1818 x, y, z = self.calcultate_scroll_position(position)
  1819 + if mask[z, y, x] < self.t0 or mask[z, y, x] > self.t1:
  1820 + return
1818 1821
1819 if self.config.target == "3D": 1822 if self.config.target == "3D":
1820 bstruct = np.array(generate_binary_structure(3, CON3D[self.config.con_3d]), dtype='uint8') 1823 bstruct = np.array(generate_binary_structure(3, CON3D[self.config.con_3d]), dtype='uint8')
1821 self.viewer.slice_.do_threshold_to_all_slices() 1824 self.viewer.slice_.do_threshold_to_all_slices()
  1825 + cp_mask = self.viewer.slice_.current_mask.matrix.copy()
1822 else: 1826 else:
1823 _bstruct = generate_binary_structure(2, CON2D[self.config.con_2d]) 1827 _bstruct = generate_binary_structure(2, CON2D[self.config.con_2d])
1824 if self.orientation == 'AXIAL': 1828 if self.orientation == 'AXIAL':
@@ -1831,11 +1835,23 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle): @@ -1831,11 +1835,23 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle):
1831 bstruct = np.zeros((3, 3, 1), dtype='uint8') 1835 bstruct = np.zeros((3, 3, 1), dtype='uint8')
1832 bstruct[:, :, 0] = _bstruct 1836 bstruct[:, :, 0] = _bstruct
1833 1837
1834 - print bstruct  
1835 - mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:]  
1836 - cp_mask = mask  
1837 1838
1838 - floodfill.floodfill_threshold(cp_mask, [[x, y, z]], self.t0, self.t1, self.fill_value, bstruct, mask) 1839 + floodfill.floodfill_threshold(mask, [[x, y, z]], self.t0, self.t1, self.fill_value, bstruct, mask)
  1840 +
  1841 + if self.config.target == '2D':
  1842 + b_mask = self.viewer.slice_.buffer_slices[self.orientation].mask
  1843 + index = self.viewer.slice_.buffer_slices[self.orientation].index
  1844 +
  1845 + if self.orientation == 'AXIAL':
  1846 + p_mask = mask[index,:,:].copy()
  1847 + elif self.orientation == 'CORONAL':
  1848 + p_mask = mask[:, index, :].copy()
  1849 + elif self.orientation == 'SAGITAL':
  1850 + p_mask = mask[:, :, index].copy()
  1851 +
  1852 + self.viewer.slice_.current_mask.save_history(index, self.orientation, p_mask, b_mask)
  1853 + else:
  1854 + self.viewer.slice_.current_mask.save_history(0, 'VOLUME', self.viewer.slice_.current_mask.matrix.copy(), cp_mask)
1839 1855
1840 self.viewer.slice_.buffer_slices['AXIAL'].discard_mask() 1856 self.viewer.slice_.buffer_slices['AXIAL'].discard_mask()
1841 self.viewer.slice_.buffer_slices['CORONAL'].discard_mask() 1857 self.viewer.slice_.buffer_slices['CORONAL'].discard_mask()