Commit 1aea71561f1f115abf940dc090e97767ce9d4ff5
1 parent
5cc84dd2
Exists in
ff_mask
Undo and Redo
Showing
4 changed files
with
42 additions
and
9 deletions
Show diff stats
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() |