Commit 3e4ed11ddd539f45e2800e17665c4f4bff817166
Committed by
GitHub
1 parent
ccf02f83
Exists in
master
Create border closed (#149)
* Created a function to pad image * taking padding in consideration when converting to vtk * Better normals computation * Added option to close border holes
Showing
6 changed files
with
146 additions
and
72 deletions
Show diff stats
invesalius/data/converters.py
@@ -21,7 +21,7 @@ import numpy | @@ -21,7 +21,7 @@ import numpy | ||
21 | import vtk | 21 | import vtk |
22 | from vtk.util import numpy_support | 22 | from vtk.util import numpy_support |
23 | 23 | ||
24 | -def to_vtk(n_array, spacing, slice_number, orientation): | 24 | +def to_vtk(n_array, spacing, slice_number, orientation, origin=(0, 0, 0), padding=(0, 0, 0)): |
25 | 25 | ||
26 | if orientation == "SAGITTAL": | 26 | if orientation == "SAGITTAL": |
27 | orientation = "SAGITAL" | 27 | orientation = "SAGITAL" |
@@ -32,20 +32,22 @@ def to_vtk(n_array, spacing, slice_number, orientation): | @@ -32,20 +32,22 @@ def to_vtk(n_array, spacing, slice_number, orientation): | ||
32 | dy, dx = n_array.shape | 32 | dy, dx = n_array.shape |
33 | dz = 1 | 33 | dz = 1 |
34 | 34 | ||
35 | + px, py, pz = padding | ||
36 | + | ||
35 | v_image = numpy_support.numpy_to_vtk(n_array.flat) | 37 | v_image = numpy_support.numpy_to_vtk(n_array.flat) |
36 | 38 | ||
37 | if orientation == 'AXIAL': | 39 | if orientation == 'AXIAL': |
38 | - extent = (0, dx -1, 0, dy -1, slice_number, slice_number + dz - 1) | 40 | + extent = (0 - px , dx -1 - px, 0 - py, dy - 1 - py, slice_number - pz, slice_number + dz - 1 - pz) |
39 | elif orientation == 'SAGITAL': | 41 | elif orientation == 'SAGITAL': |
40 | dx, dy, dz = dz, dx, dy | 42 | dx, dy, dz = dz, dx, dy |
41 | - extent = (slice_number, slice_number + dx - 1, 0, dy - 1, 0, dz - 1) | 43 | + extent = (slice_number - px, slice_number + dx - 1 - px, 0 - py, dy - 1 - py, 0 - pz, dz - 1 - pz) |
42 | elif orientation == 'CORONAL': | 44 | elif orientation == 'CORONAL': |
43 | dx, dy, dz = dx, dz, dy | 45 | dx, dy, dz = dx, dz, dy |
44 | - extent = (0, dx - 1, slice_number, slice_number + dy - 1, 0, dz - 1) | 46 | + extent = (0 - px, dx - 1 - px, slice_number - py, slice_number + dy - 1 - py, 0 - pz, dz - 1 - pz) |
45 | 47 | ||
46 | # Generating the vtkImageData | 48 | # Generating the vtkImageData |
47 | image = vtk.vtkImageData() | 49 | image = vtk.vtkImageData() |
48 | - image.SetOrigin(0, 0, 0) | 50 | + image.SetOrigin(origin) |
49 | image.SetSpacing(spacing) | 51 | image.SetSpacing(spacing) |
50 | image.SetDimensions(dx, dy, dz) | 52 | image.SetDimensions(dx, dy, dz) |
51 | # SetNumberOfScalarComponents and SetScalrType were replaced by | 53 | # SetNumberOfScalarComponents and SetScalrType were replaced by |
invesalius/data/imagedata_utils.py
@@ -751,3 +751,22 @@ def imgnormalize(data, srange=(0, 255)): | @@ -751,3 +751,22 @@ def imgnormalize(data, srange=(0, 255)): | ||
751 | datan = datan.astype(numpy.int16) | 751 | datan = datan.astype(numpy.int16) |
752 | 752 | ||
753 | return datan | 753 | return datan |
754 | + | ||
755 | + | ||
756 | +def pad_image(image, pad_value, pad_bottom, pad_top): | ||
757 | + dz, dy, dx = image.shape | ||
758 | + z_iadd = 0 | ||
759 | + z_eadd = 0 | ||
760 | + if pad_bottom: | ||
761 | + z_iadd = 1 | ||
762 | + dz += 1 | ||
763 | + if pad_top: | ||
764 | + z_eadd = 1 | ||
765 | + dz += 1 | ||
766 | + new_shape = dz, dy + 2, dx + 2 | ||
767 | + | ||
768 | + paded_image = numpy.empty(shape=new_shape, dtype=image.dtype) | ||
769 | + paded_image[:] = pad_value | ||
770 | + paded_image[z_iadd: z_iadd + image.shape[0], 1:-1, 1:-1] = image | ||
771 | + | ||
772 | + return paded_image |
invesalius/data/surface.py
@@ -538,6 +538,8 @@ class SurfaceManager(): | @@ -538,6 +538,8 @@ class SurfaceManager(): | ||
538 | fill_holes = surface_parameters['options']['fill'] | 538 | fill_holes = surface_parameters['options']['fill'] |
539 | keep_largest = surface_parameters['options']['keep_largest'] | 539 | keep_largest = surface_parameters['options']['keep_largest'] |
540 | 540 | ||
541 | + fill_border_holes = surface_parameters['options'].get('fill_border_holes', True) | ||
542 | + | ||
541 | mode = 'CONTOUR' # 'GRAYSCALE' | 543 | mode = 'CONTOUR' # 'GRAYSCALE' |
542 | min_value, max_value = mask.threshold_range | 544 | min_value, max_value = mask.threshold_range |
543 | colour = mask.colour[:3] | 545 | colour = mask.colour[:3] |
@@ -598,7 +600,7 @@ class SurfaceManager(): | @@ -598,7 +600,7 @@ class SurfaceManager(): | ||
598 | smooth_relaxation_factor, | 600 | smooth_relaxation_factor, |
599 | smooth_iterations, language, flip_image, | 601 | smooth_iterations, language, flip_image, |
600 | algorithm != 'Default', algorithm, | 602 | algorithm != 'Default', algorithm, |
601 | - imagedata_resolution), | 603 | + imagedata_resolution, fill_border_holes), |
602 | callback=lambda x: filenames.append(x)) | 604 | callback=lambda x: filenames.append(x)) |
603 | 605 | ||
604 | while len(filenames) != n_pieces: | 606 | while len(filenames) != n_pieces: |
@@ -659,7 +661,7 @@ class SurfaceManager(): | @@ -659,7 +661,7 @@ class SurfaceManager(): | ||
659 | smooth_relaxation_factor, | 661 | smooth_relaxation_factor, |
660 | smooth_iterations, language, flip_image, | 662 | smooth_iterations, language, flip_image, |
661 | algorithm != 'Default', algorithm, | 663 | algorithm != 'Default', algorithm, |
662 | - imagedata_resolution), | 664 | + imagedata_resolution, fill_border_holes), |
663 | callback=lambda x: filenames.append(x), | 665 | callback=lambda x: filenames.append(x), |
664 | error_callback=functools.partial(self._on_callback_error, | 666 | error_callback=functools.partial(self._on_callback_error, |
665 | dialog=sp)) | 667 | dialog=sp)) |
@@ -673,7 +675,7 @@ class SurfaceManager(): | @@ -673,7 +675,7 @@ class SurfaceManager(): | ||
673 | smooth_relaxation_factor, | 675 | smooth_relaxation_factor, |
674 | smooth_iterations, language, flip_image, | 676 | smooth_iterations, language, flip_image, |
675 | algorithm != 'Default', algorithm, | 677 | algorithm != 'Default', algorithm, |
676 | - imagedata_resolution), | 678 | + imagedata_resolution, fill_border_holes), |
677 | callback=lambda x: filenames.append(x)) | 679 | callback=lambda x: filenames.append(x)) |
678 | 680 | ||
679 | while len(filenames) != n_pieces: | 681 | while len(filenames) != n_pieces: |
invesalius/data/surface_process.py
@@ -14,7 +14,7 @@ import vtk | @@ -14,7 +14,7 @@ import vtk | ||
14 | import invesalius.i18n as i18n | 14 | import invesalius.i18n as i18n |
15 | import invesalius.data.converters as converters | 15 | import invesalius.data.converters as converters |
16 | from invesalius.data import cy_mesh | 16 | from invesalius.data import cy_mesh |
17 | -# import invesalius.data.imagedata_utils as iu | 17 | +import invesalius.data.imagedata_utils as iu |
18 | 18 | ||
19 | import weakref | 19 | import weakref |
20 | from scipy import ndimage | 20 | from scipy import ndimage |
@@ -45,15 +45,25 @@ def create_surface_piece(filename, shape, dtype, mask_filename, mask_shape, | @@ -45,15 +45,25 @@ def create_surface_piece(filename, shape, dtype, mask_filename, mask_shape, | ||
45 | mask_dtype, roi, spacing, mode, min_value, max_value, | 45 | mask_dtype, roi, spacing, mode, min_value, max_value, |
46 | decimate_reduction, smooth_relaxation_factor, | 46 | decimate_reduction, smooth_relaxation_factor, |
47 | smooth_iterations, language, flip_image, | 47 | smooth_iterations, language, flip_image, |
48 | - from_binary, algorithm, imagedata_resolution): | 48 | + from_binary, algorithm, imagedata_resolution, fill_border_holes): |
49 | + | ||
50 | + pad_bottom = (roi.start == 0) | ||
51 | + pad_top = (roi.stop >= shape[0]) | ||
52 | + | ||
53 | + if fill_border_holes: | ||
54 | + padding = (1, 1, pad_bottom) | ||
55 | + else: | ||
56 | + padding = (0, 0, 0) | ||
57 | + | ||
49 | if from_binary: | 58 | if from_binary: |
50 | mask = numpy.memmap(mask_filename, mode='r', | 59 | mask = numpy.memmap(mask_filename, mode='r', |
51 | dtype=mask_dtype, | 60 | dtype=mask_dtype, |
52 | shape=mask_shape) | 61 | shape=mask_shape) |
53 | - a_mask = numpy.array(mask[roi.start + 1: roi.stop + 1, | ||
54 | - 1:, 1:]) | ||
55 | - image = converters.to_vtk(a_mask, spacing, roi.start, | ||
56 | - "AXIAL") | 62 | + if fill_border_holes: |
63 | + a_mask = iu.pad_image(mask[roi.start + 1: roi.stop + 1, 1:, 1:], 0, pad_bottom, pad_top) | ||
64 | + else: | ||
65 | + a_mask = numpy.array(mask[roi.start + 1: roi.stop + 1, 1:, 1:]) | ||
66 | + image = converters.to_vtk(a_mask, spacing, roi.start, "AXIAL", padding=padding) | ||
57 | del a_mask | 67 | del a_mask |
58 | else: | 68 | else: |
59 | image = numpy.memmap(filename, mode='r', dtype=dtype, | 69 | image = numpy.memmap(filename, mode='r', dtype=dtype, |
@@ -61,16 +71,21 @@ def create_surface_piece(filename, shape, dtype, mask_filename, mask_shape, | @@ -61,16 +71,21 @@ def create_surface_piece(filename, shape, dtype, mask_filename, mask_shape, | ||
61 | mask = numpy.memmap(mask_filename, mode='r', | 71 | mask = numpy.memmap(mask_filename, mode='r', |
62 | dtype=mask_dtype, | 72 | dtype=mask_dtype, |
63 | shape=mask_shape) | 73 | shape=mask_shape) |
64 | - a_image = numpy.array(image[roi]) | 74 | + if fill_border_holes: |
75 | + a_image = iu.pad_image(image[roi], numpy.iinfo(image.dtype).min, pad_bottom, pad_top) | ||
76 | + else: | ||
77 | + a_image = numpy.array(image[roi]) | ||
78 | + # if z_iadd: | ||
79 | + # a_image[0, 1:-1, 1:-1] = image[0] | ||
80 | + # if z_eadd: | ||
81 | + # a_image[-1, 1:-1, 1:-1] = image[-1] | ||
65 | 82 | ||
66 | if algorithm == u'InVesalius 3.b2': | 83 | if algorithm == u'InVesalius 3.b2': |
67 | - a_mask = numpy.array(mask[roi.start + 1: roi.stop + 1, | ||
68 | - 1:, 1:]) | 84 | + a_mask = numpy.array(mask[roi.start + 1: roi.stop + 1, 1:, 1:]) |
69 | a_image[a_mask == 1] = a_image.min() - 1 | 85 | a_image[a_mask == 1] = a_image.min() - 1 |
70 | a_image[a_mask == 254] = (min_value + max_value) / 2.0 | 86 | a_image[a_mask == 254] = (min_value + max_value) / 2.0 |
71 | 87 | ||
72 | - image = converters.to_vtk(a_image, spacing, roi.start, | ||
73 | - "AXIAL") | 88 | + image = converters.to_vtk(a_image, spacing, roi.start, "AXIAL", padding=padding) |
74 | 89 | ||
75 | gauss = vtk.vtkImageGaussianSmooth() | 90 | gauss = vtk.vtkImageGaussianSmooth() |
76 | gauss.SetInputData(image) | 91 | gauss.SetInputData(image) |
@@ -83,8 +98,11 @@ def create_surface_piece(filename, shape, dtype, mask_filename, mask_shape, | @@ -83,8 +98,11 @@ def create_surface_piece(filename, shape, dtype, mask_filename, mask_shape, | ||
83 | del gauss | 98 | del gauss |
84 | del a_mask | 99 | del a_mask |
85 | else: | 100 | else: |
86 | - image = converters.to_vtk(a_image, spacing, roi.start, | ||
87 | - "AXIAL") | 101 | + # if z_iadd: |
102 | + # origin = -spacing[0], -spacing[1], -spacing[2] | ||
103 | + # else: | ||
104 | + # origin = 0, -spacing[1], -spacing[2] | ||
105 | + image = converters.to_vtk(a_image, spacing, roi.start, "AXIAL", padding=padding) | ||
88 | del a_image | 106 | del a_image |
89 | 107 | ||
90 | if imagedata_resolution: | 108 | if imagedata_resolution: |
@@ -97,6 +115,11 @@ def create_surface_piece(filename, shape, dtype, mask_filename, mask_shape, | @@ -97,6 +115,11 @@ def create_surface_piece(filename, shape, dtype, mask_filename, mask_shape, | ||
97 | flip.ReleaseDataFlagOn() | 115 | flip.ReleaseDataFlagOn() |
98 | flip.Update() | 116 | flip.Update() |
99 | 117 | ||
118 | + # writer = vtk.vtkXMLImageDataWriter() | ||
119 | + # writer.SetFileName('/tmp/camboja.vti') | ||
120 | + # writer.SetInputData(flip.GetOutput()) | ||
121 | + # writer.Write() | ||
122 | + | ||
100 | del image | 123 | del image |
101 | image = flip.GetOutput() | 124 | image = flip.GetOutput() |
102 | del flip | 125 | del flip |
@@ -224,34 +247,34 @@ def join_process_surface(filenames, algorithm, smooth_iterations, smooth_relaxat | @@ -224,34 +247,34 @@ def join_process_surface(filenames, algorithm, smooth_iterations, smooth_relaxat | ||
224 | 247 | ||
225 | # polydata.SetSource(None) | 248 | # polydata.SetSource(None) |
226 | # polydata.DebugOn() | 249 | # polydata.DebugOn() |
227 | - else: | ||
228 | - #smoother = vtk.vtkWindowedSincPolyDataFilter() | ||
229 | - send_message('Smoothing ...') | ||
230 | - smoother = vtk.vtkSmoothPolyDataFilter() | ||
231 | - smoother_ref = weakref.ref(smoother) | ||
232 | - # smoother_ref().AddObserver("ProgressEvent", lambda obj,evt: | ||
233 | - # UpdateProgress(smoother_ref(), _("Creating 3D surface..."))) | ||
234 | - smoother.SetInputData(polydata) | ||
235 | - smoother.SetNumberOfIterations(smooth_iterations) | ||
236 | - smoother.SetRelaxationFactor(smooth_relaxation_factor) | ||
237 | - smoother.SetFeatureAngle(80) | ||
238 | - #smoother.SetEdgeAngle(90.0) | ||
239 | - #smoother.SetPassBand(0.1) | ||
240 | - smoother.BoundarySmoothingOn() | ||
241 | - smoother.FeatureEdgeSmoothingOn() | ||
242 | - #smoother.NormalizeCoordinatesOn() | ||
243 | - #smoother.NonManifoldSmoothingOn() | ||
244 | - # smoother.ReleaseDataFlagOn() | ||
245 | - # smoother.GetOutput().ReleaseDataFlagOn() | ||
246 | - smoother.Update() | ||
247 | - del polydata | ||
248 | - polydata = smoother.GetOutput() | ||
249 | - #polydata.Register(None) | ||
250 | - # polydata.SetSource(None) | ||
251 | - del smoother | ||
252 | - | ||
253 | - | ||
254 | - if decimate_reduction: | 250 | + # else: |
251 | + # #smoother = vtk.vtkWindowedSincPolyDataFilter() | ||
252 | + # send_message('Smoothing ...') | ||
253 | + # smoother = vtk.vtkSmoothPolyDataFilter() | ||
254 | + # smoother_ref = weakref.ref(smoother) | ||
255 | + # # smoother_ref().AddObserver("ProgressEvent", lambda obj,evt: | ||
256 | + # # UpdateProgress(smoother_ref(), _("Creating 3D surface..."))) | ||
257 | + # smoother.SetInputData(polydata) | ||
258 | + # smoother.SetNumberOfIterations(smooth_iterations) | ||
259 | + # smoother.SetRelaxationFactor(smooth_relaxation_factor) | ||
260 | + # smoother.SetFeatureAngle(80) | ||
261 | + # #smoother.SetEdgeAngle(90.0) | ||
262 | + # #smoother.SetPassBand(0.1) | ||
263 | + # smoother.BoundarySmoothingOn() | ||
264 | + # smoother.FeatureEdgeSmoothingOn() | ||
265 | + # #smoother.NormalizeCoordinatesOn() | ||
266 | + # #smoother.NonManifoldSmoothingOn() | ||
267 | + # # smoother.ReleaseDataFlagOn() | ||
268 | + # # smoother.GetOutput().ReleaseDataFlagOn() | ||
269 | + # smoother.Update() | ||
270 | + # del polydata | ||
271 | + # polydata = smoother.GetOutput() | ||
272 | + # #polydata.Register(None) | ||
273 | + # # polydata.SetSource(None) | ||
274 | + # del smoother | ||
275 | + | ||
276 | + | ||
277 | + if not decimate_reduction: | ||
255 | print("Decimating", decimate_reduction) | 278 | print("Decimating", decimate_reduction) |
256 | send_message('Decimating ...') | 279 | send_message('Decimating ...') |
257 | decimation = vtk.vtkQuadricDecimation() | 280 | decimation = vtk.vtkQuadricDecimation() |
@@ -320,9 +343,11 @@ def join_process_surface(filenames, algorithm, smooth_iterations, smooth_relaxat | @@ -320,9 +343,11 @@ def join_process_surface(filenames, algorithm, smooth_iterations, smooth_relaxat | ||
320 | # normals_ref().AddObserver("ProgressEvent", lambda obj,evt: | 343 | # normals_ref().AddObserver("ProgressEvent", lambda obj,evt: |
321 | # UpdateProgress(normals_ref(), _("Creating 3D surface..."))) | 344 | # UpdateProgress(normals_ref(), _("Creating 3D surface..."))) |
322 | normals.SetInputData(polydata) | 345 | normals.SetInputData(polydata) |
323 | - # normals.SetFeatureAngle(80) | ||
324 | - # normals.SplittingOff() | ||
325 | - # normals.AutoOrientNormalsOn() | 346 | + normals.SetFeatureAngle(80) |
347 | + normals.SplittingOn() | ||
348 | + normals.AutoOrientNormalsOn() | ||
349 | + normals.NonManifoldTraversalOn() | ||
350 | + normals.ComputeCellNormalsOn() | ||
326 | # normals.GetOutput().ReleaseDataFlagOn() | 351 | # normals.GetOutput().ReleaseDataFlagOn() |
327 | normals.Update() | 352 | normals.Update() |
328 | del polydata | 353 | del polydata |
@@ -332,22 +357,22 @@ def join_process_surface(filenames, algorithm, smooth_iterations, smooth_relaxat | @@ -332,22 +357,22 @@ def join_process_surface(filenames, algorithm, smooth_iterations, smooth_relaxat | ||
332 | del normals | 357 | del normals |
333 | 358 | ||
334 | 359 | ||
335 | - # Improve performance | ||
336 | - stripper = vtk.vtkStripper() | ||
337 | - # stripper.ReleaseDataFlagOn() | ||
338 | - # stripper_ref = weakref.ref(stripper) | ||
339 | - # stripper_ref().AddObserver("ProgressEvent", lambda obj,evt: | ||
340 | - # UpdateProgress(stripper_ref(), _("Creating 3D surface..."))) | ||
341 | - stripper.SetInputData(polydata) | ||
342 | - stripper.PassThroughCellIdsOn() | ||
343 | - stripper.PassThroughPointIdsOn() | ||
344 | - # stripper.GetOutput().ReleaseDataFlagOn() | ||
345 | - stripper.Update() | ||
346 | - del polydata | ||
347 | - polydata = stripper.GetOutput() | ||
348 | - #polydata.Register(None) | ||
349 | - # polydata.SetSource(None) | ||
350 | - del stripper | 360 | + # # Improve performance |
361 | + # stripper = vtk.vtkStripper() | ||
362 | + # # stripper.ReleaseDataFlagOn() | ||
363 | + # # stripper_ref = weakref.ref(stripper) | ||
364 | + # # stripper_ref().AddObserver("ProgressEvent", lambda obj,evt: | ||
365 | + # # UpdateProgress(stripper_ref(), _("Creating 3D surface..."))) | ||
366 | + # stripper.SetInputData(polydata) | ||
367 | + # stripper.PassThroughCellIdsOn() | ||
368 | + # stripper.PassThroughPointIdsOn() | ||
369 | + # # stripper.GetOutput().ReleaseDataFlagOn() | ||
370 | + # stripper.Update() | ||
371 | + # del polydata | ||
372 | + # polydata = stripper.GetOutput() | ||
373 | + # #polydata.Register(None) | ||
374 | + # # polydata.SetSource(None) | ||
375 | + # del stripper | ||
351 | 376 | ||
352 | send_message('Calculating area and volume ...') | 377 | send_message('Calculating area and volume ...') |
353 | measured_polydata = vtk.vtkMassProperties() | 378 | measured_polydata = vtk.vtkMassProperties() |
invesalius/gui/dialogs.py
@@ -1662,7 +1662,10 @@ class SurfaceCreationOptionsPanel(wx.Panel): | @@ -1662,7 +1662,10 @@ class SurfaceCreationOptionsPanel(wx.Panel): | ||
1662 | (combo_quality, 0, flag_button, 0)]) | 1662 | (combo_quality, 0, flag_button, 0)]) |
1663 | 1663 | ||
1664 | 1664 | ||
1665 | - # LINES 4 and 5: Checkboxes | 1665 | + # LINES 4, 5 and 6: Checkboxes |
1666 | + check_box_border_holes = wx.CheckBox(self, -1, _("Fill border holes")) | ||
1667 | + check_box_border_holes.SetValue(False) | ||
1668 | + self.check_box_border_holes = check_box_border_holes | ||
1666 | check_box_holes = wx.CheckBox(self, -1, _("Fill holes")) | 1669 | check_box_holes = wx.CheckBox(self, -1, _("Fill holes")) |
1667 | check_box_holes.SetValue(False) | 1670 | check_box_holes.SetValue(False) |
1668 | self.check_box_holes = check_box_holes | 1671 | self.check_box_holes = check_box_holes |
@@ -1673,6 +1676,7 @@ class SurfaceCreationOptionsPanel(wx.Panel): | @@ -1673,6 +1676,7 @@ class SurfaceCreationOptionsPanel(wx.Panel): | ||
1673 | # Merge all sizers and checkboxes | 1676 | # Merge all sizers and checkboxes |
1674 | sizer = wx.BoxSizer(wx.VERTICAL) | 1677 | sizer = wx.BoxSizer(wx.VERTICAL) |
1675 | sizer.Add(fixed_sizer, 0, wx.TOP|wx.RIGHT|wx.LEFT|wx.GROW|wx.EXPAND, 5) | 1678 | sizer.Add(fixed_sizer, 0, wx.TOP|wx.RIGHT|wx.LEFT|wx.GROW|wx.EXPAND, 5) |
1679 | + sizer.Add(check_box_border_holes, 0, wx.RIGHT|wx.LEFT, 5) | ||
1676 | sizer.Add(check_box_holes, 0, wx.RIGHT|wx.LEFT, 5) | 1680 | sizer.Add(check_box_holes, 0, wx.RIGHT|wx.LEFT, 5) |
1677 | sizer.Add(check_box_largest, 0, wx.RIGHT|wx.LEFT, 5) | 1681 | sizer.Add(check_box_largest, 0, wx.RIGHT|wx.LEFT, 5) |
1678 | 1682 | ||
@@ -1687,11 +1691,13 @@ class SurfaceCreationOptionsPanel(wx.Panel): | @@ -1687,11 +1691,13 @@ class SurfaceCreationOptionsPanel(wx.Panel): | ||
1687 | mask_index = self.combo_mask.GetSelection() | 1691 | mask_index = self.combo_mask.GetSelection() |
1688 | surface_name = self.text.GetValue() | 1692 | surface_name = self.text.GetValue() |
1689 | quality = const.SURFACE_QUALITY_LIST[self.combo_quality.GetSelection()] | 1693 | quality = const.SURFACE_QUALITY_LIST[self.combo_quality.GetSelection()] |
1694 | + fill_border_holes = self.check_box_border_holes.GetValue() | ||
1690 | fill_holes = self.check_box_holes.GetValue() | 1695 | fill_holes = self.check_box_holes.GetValue() |
1691 | keep_largest = self.check_box_largest.GetValue() | 1696 | keep_largest = self.check_box_largest.GetValue() |
1692 | return {"index": mask_index, | 1697 | return {"index": mask_index, |
1693 | "name": surface_name, | 1698 | "name": surface_name, |
1694 | "quality": quality, | 1699 | "quality": quality, |
1700 | + "fill_border_holes": fill_border_holes, | ||
1695 | "fill": fill_holes, | 1701 | "fill": fill_holes, |
1696 | "keep_largest": keep_largest, | 1702 | "keep_largest": keep_largest, |
1697 | "overwrite": False} | 1703 | "overwrite": False} |
invesalius/gui/preferences.py
@@ -15,7 +15,7 @@ except ImportError: # if it's not there locally, try the wxPython lib. | @@ -15,7 +15,7 @@ except ImportError: # if it's not there locally, try the wxPython lib. | ||
15 | class Preferences(wx.Dialog): | 15 | class Preferences(wx.Dialog): |
16 | 16 | ||
17 | def __init__( self, parent, id = ID, title = _("Preferences"), size=wx.DefaultSize,\ | 17 | def __init__( self, parent, id = ID, title = _("Preferences"), size=wx.DefaultSize,\ |
18 | - pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE): | 18 | + pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER): |
19 | 19 | ||
20 | try: | 20 | try: |
21 | pre = wx.PreDialog() | 21 | pre = wx.PreDialog() |
@@ -36,14 +36,16 @@ class Preferences(wx.Dialog): | @@ -36,14 +36,16 @@ class Preferences(wx.Dialog): | ||
36 | else: | 36 | else: |
37 | self.book = fnb.FlatNotebook(self, wx.ID_ANY, agwStyle=bookStyle) | 37 | self.book = fnb.FlatNotebook(self, wx.ID_ANY, agwStyle=bookStyle) |
38 | 38 | ||
39 | - sizer.Add(self.book, 80, wx.EXPAND|wx.ALL) | 39 | + sizer.Add(self.book, 1, wx.EXPAND|wx.ALL) |
40 | 40 | ||
41 | self.pnl_viewer2d = Viewer2D(self) | 41 | self.pnl_viewer2d = Viewer2D(self) |
42 | self.pnl_viewer3d = Viewer3D(self) | 42 | self.pnl_viewer3d = Viewer3D(self) |
43 | + # self.pnl_surface = SurfaceCreation(self) | ||
43 | self.pnl_language = Language(self) | 44 | self.pnl_language = Language(self) |
44 | 45 | ||
45 | self.book.AddPage(self.pnl_viewer2d, _("2D Visualization")) | 46 | self.book.AddPage(self.pnl_viewer2d, _("2D Visualization")) |
46 | self.book.AddPage(self.pnl_viewer3d, _("3D Visualization")) | 47 | self.book.AddPage(self.pnl_viewer3d, _("3D Visualization")) |
48 | + # self.book.AddPage(self.pnl_surface, _("Surface creation")) | ||
47 | self.book.AddPage(self.pnl_language, _("Language")) | 49 | self.book.AddPage(self.pnl_language, _("Language")) |
48 | 50 | ||
49 | line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL) | 51 | line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL) |
@@ -59,7 +61,7 @@ class Preferences(wx.Dialog): | @@ -59,7 +61,7 @@ class Preferences(wx.Dialog): | ||
59 | 61 | ||
60 | btnsizer.Realize() | 62 | btnsizer.Realize() |
61 | 63 | ||
62 | - sizer.Add(btnsizer, 10, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP|wx.BOTTOM, 5) | 64 | + sizer.Add(btnsizer, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP|wx.BOTTOM, 5) |
63 | 65 | ||
64 | self.SetSizer(sizer) | 66 | self.SetSizer(sizer) |
65 | sizer.Fit(self) | 67 | sizer.Fit(self) |
@@ -214,3 +216,21 @@ class Language(wx.Panel): | @@ -214,3 +216,21 @@ class Language(wx.Panel): | ||
214 | locales = self.lg.GetLocalesKey() | 216 | locales = self.lg.GetLocalesKey() |
215 | selection = locales.index(language) | 217 | selection = locales.index(language) |
216 | self.cmb_lang.SetSelection(int(selection)) | 218 | self.cmb_lang.SetSelection(int(selection)) |
219 | + | ||
220 | + | ||
221 | + | ||
222 | +class SurfaceCreation(wx.Panel): | ||
223 | + def __init__(self, parent): | ||
224 | + wx.Panel.__init__(self, parent) | ||
225 | + self.rb_fill_border = wx.RadioBox(self, -1, "Fill border holes", choices=[_('Yes'), _('No')], style=wx.RA_SPECIFY_COLS | wx.NO_BORDER) | ||
226 | + | ||
227 | + sizer = wx.BoxSizer(wx.VERTICAL) | ||
228 | + sizer.Add(self.rb_fill_border) | ||
229 | + | ||
230 | + self.SetSizerAndFit(sizer) | ||
231 | + | ||
232 | + def GetSelection(self): | ||
233 | + return {} | ||
234 | + | ||
235 | + def LoadSelection(self, values): | ||
236 | + pass |