Commit 2c9f1dc3e11f144a94eee586edf61a86b17338c5
Committed by
GitHub
1 parent
7c1411a5
Exists in
master
and in
21 other branches
Gui improvements to Fill holes and remove parts (#48)
Improved the dialog interface used to config the fill holes and remove parts. Also, when using 3D connectivity, it show a progressdialog.
Showing
2 changed files
with
76 additions
and
42 deletions
Show diff stats
invesalius/data/styles.py
... | ... | @@ -22,6 +22,8 @@ import multiprocessing |
22 | 22 | import tempfile |
23 | 23 | import time |
24 | 24 | |
25 | +from concurrent import futures | |
26 | + | |
25 | 27 | import vtk |
26 | 28 | import wx |
27 | 29 | |
... | ... | @@ -1779,6 +1781,8 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle): |
1779 | 1781 | self.fill_value = 254 |
1780 | 1782 | |
1781 | 1783 | self._dlg_title = _(u"Fill holes") |
1784 | + self._progr_title = _(u"Fill hole") | |
1785 | + self._progr_msg = _(u"Filling hole ...") | |
1782 | 1786 | |
1783 | 1787 | self.AddObserver("LeftButtonPressEvent", self.OnFFClick) |
1784 | 1788 | |
... | ... | @@ -1837,10 +1841,8 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle): |
1837 | 1841 | bstruct = np.zeros((3, 3, 1), dtype='uint8') |
1838 | 1842 | bstruct[:, :, 0] = _bstruct |
1839 | 1843 | |
1840 | - | |
1841 | - floodfill.floodfill_threshold(mask, [[x, y, z]], self.t0, self.t1, self.fill_value, bstruct, mask) | |
1842 | - | |
1843 | 1844 | if self.config.target == '2D': |
1845 | + floodfill.floodfill_threshold(mask, [[x, y, z]], self.t0, self.t1, self.fill_value, bstruct, mask) | |
1844 | 1846 | b_mask = self.viewer.slice_.buffer_slices[self.orientation].mask |
1845 | 1847 | index = self.viewer.slice_.buffer_slices[self.orientation].index |
1846 | 1848 | |
... | ... | @@ -1853,6 +1855,16 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle): |
1853 | 1855 | |
1854 | 1856 | self.viewer.slice_.current_mask.save_history(index, self.orientation, p_mask, b_mask) |
1855 | 1857 | else: |
1858 | + with futures.ThreadPoolExecutor(max_workers=1) as executor: | |
1859 | + future = executor.submit(floodfill.floodfill_threshold, mask, [[x, y, z]], self.t0, self.t1, self.fill_value, bstruct, mask) | |
1860 | + | |
1861 | + dlg = wx.ProgressDialog(self._progr_title, self._progr_msg, parent=None, style=wx.PD_APP_MODAL) | |
1862 | + while not future.done(): | |
1863 | + dlg.Pulse() | |
1864 | + time.sleep(0.1) | |
1865 | + | |
1866 | + dlg.Destroy() | |
1867 | + | |
1856 | 1868 | self.viewer.slice_.current_mask.save_history(0, 'VOLUME', self.viewer.slice_.current_mask.matrix.copy(), cp_mask) |
1857 | 1869 | |
1858 | 1870 | self.viewer.slice_.buffer_slices['AXIAL'].discard_mask() |
... | ... | @@ -1912,6 +1924,8 @@ class RemoveMaskPartsInteractorStyle(FloodFillMaskInteractorStyle): |
1912 | 1924 | self.fill_value = 1 |
1913 | 1925 | |
1914 | 1926 | self._dlg_title = _(u"Remove parts") |
1927 | + self._progr_title = _(u"Remove part") | |
1928 | + self._progr_msg = _(u"Removing part ...") | |
1915 | 1929 | |
1916 | 1930 | |
1917 | 1931 | def get_style(style): | ... | ... |
invesalius/gui/dialogs.py
... | ... | @@ -1851,14 +1851,11 @@ class FFillOptionsDialog(wx.Dialog): |
1851 | 1851 | self._init_gui() |
1852 | 1852 | |
1853 | 1853 | def _init_gui(self): |
1854 | - sizer = wx.GridBagSizer(5, 6) | |
1855 | - | |
1856 | - flag_labels = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | |
1857 | - | |
1858 | - # self.target = wx.RadioBox(self, -1, "", | |
1859 | - # choices=[_(u"2D - Actual slice"), _(u"3D - Entire volume")], | |
1860 | - # style=wx.NO_BORDER | wx.VERTICAL) | |
1861 | - self.target_2d = wx.RadioButton(self, -1, _(u"2D - Actual slice")) | |
1854 | + """ | |
1855 | + Create the widgets. | |
1856 | + """ | |
1857 | + # Target | |
1858 | + self.target_2d = wx.RadioButton(self, -1, _(u"2D - Actual slice"), style=wx.RB_GROUP) | |
1862 | 1859 | self.target_3d = wx.RadioButton(self, -1, _(u"3D - All slices")) |
1863 | 1860 | |
1864 | 1861 | if self.config.target == "2D": |
... | ... | @@ -1866,54 +1863,77 @@ class FFillOptionsDialog(wx.Dialog): |
1866 | 1863 | else: |
1867 | 1864 | self.target_3d.SetValue(1) |
1868 | 1865 | |
1869 | - choices2d = ["4", "8"] | |
1870 | - choices3d = ["6", "18", "26"] | |
1871 | - self.conect2D = wx.RadioBox(self, -1, _(u"2D Connectivity"), choices=choices2d, style=wx.NO_BORDER | wx.HORIZONTAL) | |
1872 | - self.conect3D = wx.RadioBox(self, -1, _(u"3D Connectivity"), choices=choices3d, style=wx.NO_BORDER | wx.HORIZONTAL) | |
1866 | + # Connectivity 2D | |
1867 | + self.conect2D_4 = wx.RadioButton(self, -1, "4", style=wx.RB_GROUP) | |
1868 | + self.conect2D_8 = wx.RadioButton(self, -1, "8") | |
1873 | 1869 | |
1874 | - try: | |
1875 | - self.conect2D.SetSelection(choices2d.index(str(self.config.con_2d))) | |
1876 | - except ValueError: | |
1877 | - print "ERROR 2D" | |
1878 | - self.conect2D.SetSelection(0) | |
1870 | + if self.config.con_2d == 8: | |
1871 | + self.conect2D_8.SetValue(1) | |
1872 | + else: | |
1873 | + self.conect2D_4.SetValue(1) | |
1879 | 1874 | self.config.con_2d = 4 |
1880 | 1875 | |
1881 | - try: | |
1882 | - self.conect3D.SetSelection(choices3d.index(str(self.config.con_3d))) | |
1883 | - except ValueError: | |
1884 | - print "ERROR 3D" | |
1885 | - self.conect3D.SetSelection(0) | |
1886 | - self.config.con_3d = 6 | |
1876 | + # Connectivity 3D | |
1877 | + self.conect3D_6 = wx.RadioButton(self, -1, "6", style=wx.RB_GROUP) | |
1878 | + self.conect3D_18 = wx.RadioButton(self, -1, "18") | |
1879 | + self.conect3D_26 = wx.RadioButton(self, -1, "26") | |
1880 | + | |
1881 | + if self.config.con_3d == 18: | |
1882 | + self.conect3D_18.SetValue(1) | |
1883 | + elif self.config.con_3d == 26: | |
1884 | + self.conect3D_26.SetValue(1) | |
1885 | + else: | |
1886 | + self.conect3D_6.SetValue(1) | |
1887 | + | |
1888 | + # Sizer | |
1889 | + sizer = wx.GridBagSizer(11, 6) | |
1890 | + sizer.AddStretchSpacer((0, 0)) | |
1891 | + | |
1892 | + sizer.Add(wx.StaticText(self, -1, _(u"Parameters")), (1, 0), (1, 6), flag=wx.LEFT, border=7) | |
1893 | + sizer.Add(self.target_2d, (2, 0), (1, 6), flag=wx.LEFT, border=9) | |
1894 | + sizer.Add(self.target_3d, (3, 0), (1, 6), flag=wx.LEFT, border=9) | |
1895 | + | |
1896 | + sizer.AddStretchSpacer((4, 0)) | |
1887 | 1897 | |
1888 | - sizer.Add(wx.StaticText(self, -1, _(u"Parameters")), (0, 0), flag=wx.TOP|wx.LEFT|wx.RIGHT, border=7) | |
1889 | - sizer.AddStretchSpacer((0, 5)) | |
1890 | - sizer.Add(self.target_2d, (1, 0), (1, 3), flag=wx.LEFT|wx.RIGHT, border=9) | |
1891 | - sizer.Add(self.target_3d, (2, 0), (1, 3), flag=wx.LEFT|wx.RIGHT, border=9) | |
1892 | - sizer.Add(self.conect2D, (3, 0), flag=wx.TOP|wx.LEFT|wx.RIGHT, border=9) | |
1893 | - sizer.Add(self.conect3D, (4, 0), flag=wx.ALL, border=9) | |
1898 | + sizer.Add(wx.StaticText(self, -1, _(u"2D Connectivity")), (5, 0), (1, 6), flag=wx.LEFT, border=9) | |
1899 | + sizer.Add(self.conect2D_4, (6, 0), flag=wx.LEFT, border=9) | |
1900 | + sizer.Add(self.conect2D_8, (6, 1), flag=wx.LEFT, border=9) | |
1901 | + | |
1902 | + sizer.AddStretchSpacer((7, 0)) | |
1903 | + | |
1904 | + sizer.Add(wx.StaticText(self, -1, _(u"3D Connectivity")), (8, 0), (1, 6), flag=wx.LEFT, border=9) | |
1905 | + sizer.Add(self.conect3D_6, (9, 0), flag=wx.LEFT, border=9) | |
1906 | + sizer.Add(self.conect3D_18, (9, 1), flag=wx.LEFT, border=9) | |
1907 | + sizer.Add(self.conect3D_26, (9, 2), flag=wx.LEFT, border=9) | |
1908 | + sizer.AddStretchSpacer((10, 0)) | |
1894 | 1909 | |
1895 | 1910 | self.SetSizer(sizer) |
1896 | 1911 | sizer.Fit(self) |
1897 | 1912 | self.Layout() |
1898 | 1913 | |
1899 | - self.Bind(wx.EVT_RADIOBUTTON, self.OnSetTarget) | |
1900 | - self.conect2D.Bind(wx.EVT_RADIOBOX, self.OnSetCon2D) | |
1901 | - self.conect3D.Bind(wx.EVT_RADIOBOX, self.OnSetCon3D) | |
1914 | + self.Bind(wx.EVT_RADIOBUTTON, self.OnSetRadio) | |
1902 | 1915 | self.Bind(wx.EVT_CLOSE, self.OnClose) |
1903 | 1916 | |
1904 | - def OnSetTarget(self, evt): | |
1917 | + def OnSetRadio(self, evt): | |
1918 | + # Target | |
1905 | 1919 | if self.target_2d.GetValue(): |
1906 | 1920 | self.config.target = "2D" |
1907 | 1921 | else: |
1908 | 1922 | self.config.target = "3D" |
1909 | 1923 | |
1910 | - def OnSetCon2D(self, evt): | |
1911 | - self.config.con_2d = int(self.conect2D.GetStringSelection()) | |
1912 | - print self.config.con_2d | |
1924 | + # 2D | |
1925 | + if self.conect2D_4.GetValue(): | |
1926 | + self.config.con_2d = 4 | |
1927 | + elif self.conect2D_8.GetValue(): | |
1928 | + self.config.con_2d = 8 | |
1913 | 1929 | |
1914 | - def OnSetCon3D(self, evt): | |
1915 | - self.config.con_3d = int(self.conect3D.GetStringSelection()) | |
1916 | - print self.config.con_3d | |
1930 | + # 3D | |
1931 | + if self.conect3D_6.GetValue(): | |
1932 | + self.config.con_3d = 6 | |
1933 | + elif self.conect3D_18.GetValue(): | |
1934 | + self.config.con_3d = 18 | |
1935 | + elif self.conect3D_26.GetValue(): | |
1936 | + self.config.con_3d = 26 | |
1917 | 1937 | |
1918 | 1938 | def OnClose(self, evt): |
1919 | 1939 | if self.config.dlg_visible: | ... | ... |