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
invesalius/data/mask.py
... | ... | @@ -60,6 +60,8 @@ class EditionHistoryNode(object): |
60 | 60 | mvolume[1:, 1:, self.index+1] = array |
61 | 61 | if self.clean: |
62 | 62 | mvolume[0, 0, self.index+1] = 1 |
63 | + elif self.orientation == 'VOLUME': | |
64 | + mvolume[:] = array | |
63 | 65 | |
64 | 66 | print "applying to", self.orientation, "at slice", self.index |
65 | 67 | |
... | ... | @@ -106,7 +108,15 @@ class EditionHistory(object): |
106 | 108 | ##self.index -= 1 |
107 | 109 | ##h[self.index].commit_history(mvolume) |
108 | 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 | 120 | self._reload_slice(self.index - 1) |
111 | 121 | else: |
112 | 122 | self.index -= 1 |
... | ... | @@ -129,7 +139,12 @@ class EditionHistory(object): |
129 | 139 | ##h[self.index].commit_history(mvolume) |
130 | 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 | 148 | self._reload_slice(self.index + 1) |
134 | 149 | else: |
135 | 150 | self.index += 1 | ... | ... |
invesalius/data/slice_.py
... | ... | @@ -1402,7 +1402,8 @@ class Slice(object): |
1402 | 1402 | buffer_slices = self.buffer_slices |
1403 | 1403 | actual_slices = {"AXIAL": buffer_slices["AXIAL"].index, |
1404 | 1404 | "CORONAL": buffer_slices["CORONAL"].index, |
1405 | - "SAGITAL": buffer_slices["SAGITAL"].index,} | |
1405 | + "SAGITAL": buffer_slices["SAGITAL"].index, | |
1406 | + "VOLUME": 0} | |
1406 | 1407 | self.current_mask.undo_history(actual_slices) |
1407 | 1408 | for o in self.buffer_slices: |
1408 | 1409 | self.buffer_slices[o].discard_mask() |
... | ... | @@ -1413,7 +1414,8 @@ class Slice(object): |
1413 | 1414 | buffer_slices = self.buffer_slices |
1414 | 1415 | actual_slices = {"AXIAL": buffer_slices["AXIAL"].index, |
1415 | 1416 | "CORONAL": buffer_slices["CORONAL"].index, |
1416 | - "SAGITAL": buffer_slices["SAGITAL"].index,} | |
1417 | + "SAGITAL": buffer_slices["SAGITAL"].index, | |
1418 | + "VOLUME": 0} | |
1417 | 1419 | self.current_mask.redo_history(actual_slices) |
1418 | 1420 | for o in self.buffer_slices: |
1419 | 1421 | self.buffer_slices[o].discard_mask() | ... | ... |
invesalius/data/styles.py
... | ... | @@ -1814,11 +1814,15 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle): |
1814 | 1814 | if position < 0: |
1815 | 1815 | position = viewer.calculate_matrix_position(coord) |
1816 | 1816 | |
1817 | + mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:] | |
1817 | 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 | 1822 | if self.config.target == "3D": |
1820 | 1823 | bstruct = np.array(generate_binary_structure(3, CON3D[self.config.con_3d]), dtype='uint8') |
1821 | 1824 | self.viewer.slice_.do_threshold_to_all_slices() |
1825 | + cp_mask = self.viewer.slice_.current_mask.matrix.copy() | |
1822 | 1826 | else: |
1823 | 1827 | _bstruct = generate_binary_structure(2, CON2D[self.config.con_2d]) |
1824 | 1828 | if self.orientation == 'AXIAL': |
... | ... | @@ -1831,11 +1835,23 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle): |
1831 | 1835 | bstruct = np.zeros((3, 3, 1), dtype='uint8') |
1832 | 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 | 1856 | self.viewer.slice_.buffer_slices['AXIAL'].discard_mask() |
1841 | 1857 | self.viewer.slice_.buffer_slices['CORONAL'].discard_mask() | ... | ... |