Commit ac56cedc3582840918ca2c8859961e17524b8b7c
1 parent
3a497a13
Exists in
inv3.0.1
Surface area (#37)
* Calculating surface area * remove prints * Updating surface info when overwriting surface * Calculating area when selecting greatest surface, select surface or separate all surfaces * Copying area when duplicating surface
Showing
2 changed files
with
43 additions
and
22 deletions
Show diff stats
invesalius/data/surface.py
@@ -59,7 +59,8 @@ class Surface(): | @@ -59,7 +59,8 @@ class Surface(): | ||
59 | self.polydata = '' | 59 | self.polydata = '' |
60 | self.colour = '' | 60 | self.colour = '' |
61 | self.transparency = const.SURFACE_TRANSPARENCY | 61 | self.transparency = const.SURFACE_TRANSPARENCY |
62 | - self.volume = 0 | 62 | + self.volume = 0.0 |
63 | + self.area = 0.0 | ||
63 | self.is_shown = 1 | 64 | self.is_shown = 1 |
64 | if not name: | 65 | if not name: |
65 | self.name = const.SURFACE_NAME_PATTERN %(self.index+1) | 66 | self.name = const.SURFACE_NAME_PATTERN %(self.index+1) |
@@ -81,6 +82,7 @@ class Surface(): | @@ -81,6 +82,7 @@ class Surface(): | ||
81 | 'transparency': self.transparency, | 82 | 'transparency': self.transparency, |
82 | 'visible': bool(self.is_shown), | 83 | 'visible': bool(self.is_shown), |
83 | 'volume': self.volume, | 84 | 'volume': self.volume, |
85 | + 'area': self.area, | ||
84 | } | 86 | } |
85 | plist_filename = filename + '.plist' | 87 | plist_filename = filename + '.plist' |
86 | #plist_filepath = os.path.join(dir_temp, filename + '.plist') | 88 | #plist_filepath = os.path.join(dir_temp, filename + '.plist') |
@@ -100,6 +102,10 @@ class Surface(): | @@ -100,6 +102,10 @@ class Surface(): | ||
100 | self.transparency = sp['transparency'] | 102 | self.transparency = sp['transparency'] |
101 | self.is_shown = sp['visible'] | 103 | self.is_shown = sp['visible'] |
102 | self.volume = sp['volume'] | 104 | self.volume = sp['volume'] |
105 | + try: | ||
106 | + self.area = sp['area'] | ||
107 | + except KeyError: | ||
108 | + self.area = 0.0 | ||
103 | self.polydata = pu.Import(os.path.join(dirpath, sp['polydata'])) | 109 | self.polydata = pu.Import(os.path.join(dirpath, sp['polydata'])) |
104 | Surface.general_index = max(Surface.general_index, self.index) | 110 | Surface.general_index = max(Surface.general_index, self.index) |
105 | 111 | ||
@@ -164,7 +170,8 @@ class SurfaceManager(): | @@ -164,7 +170,8 @@ class SurfaceManager(): | ||
164 | name = new_name, | 170 | name = new_name, |
165 | colour = original_surface.colour, | 171 | colour = original_surface.colour, |
166 | transparency = original_surface.transparency, | 172 | transparency = original_surface.transparency, |
167 | - volume = original_surface.volume) | 173 | + volume = original_surface.volume, |
174 | + area = original_surface.area) | ||
168 | 175 | ||
169 | def OnRemove(self, pubsub_evt): | 176 | def OnRemove(self, pubsub_evt): |
170 | selected_items = pubsub_evt.data | 177 | selected_items = pubsub_evt.data |
@@ -240,7 +247,7 @@ class SurfaceManager(): | @@ -240,7 +247,7 @@ class SurfaceManager(): | ||
240 | 247 | ||
241 | def CreateSurfaceFromPolydata(self, polydata, overwrite=False, | 248 | def CreateSurfaceFromPolydata(self, polydata, overwrite=False, |
242 | name=None, colour=None, | 249 | name=None, colour=None, |
243 | - transparency=None, volume=None): | 250 | + transparency=None, volume=None, area=None): |
244 | normals = vtk.vtkPolyDataNormals() | 251 | normals = vtk.vtkPolyDataNormals() |
245 | normals.SetInputData(polydata) | 252 | normals.SetInputData(polydata) |
246 | normals.SetFeatureAngle(80) | 253 | normals.SetFeatureAngle(80) |
@@ -290,7 +297,7 @@ class SurfaceManager(): | @@ -290,7 +297,7 @@ class SurfaceManager(): | ||
290 | session.ChangeProject() | 297 | session.ChangeProject() |
291 | 298 | ||
292 | # The following lines have to be here, otherwise all volumes disappear | 299 | # The following lines have to be here, otherwise all volumes disappear |
293 | - if not volume: | 300 | + if not volume or not area: |
294 | triangle_filter = vtk.vtkTriangleFilter() | 301 | triangle_filter = vtk.vtkTriangleFilter() |
295 | triangle_filter.SetInputData(polydata) | 302 | triangle_filter.SetInputData(polydata) |
296 | triangle_filter.Update() | 303 | triangle_filter.Update() |
@@ -299,18 +306,22 @@ class SurfaceManager(): | @@ -299,18 +306,22 @@ class SurfaceManager(): | ||
299 | measured_polydata.SetInputConnection(triangle_filter.GetOutputPort()) | 306 | measured_polydata.SetInputConnection(triangle_filter.GetOutputPort()) |
300 | measured_polydata.Update() | 307 | measured_polydata.Update() |
301 | volume = measured_polydata.GetVolume() | 308 | volume = measured_polydata.GetVolume() |
309 | + area = measured_polydata.GetSurfaceArea() | ||
302 | surface.volume = volume | 310 | surface.volume = volume |
311 | + surface.area = area | ||
303 | print ">>>>", surface.volume | 312 | print ">>>>", surface.volume |
304 | else: | 313 | else: |
305 | surface.volume = volume | 314 | surface.volume = volume |
315 | + surface.area = area | ||
316 | + | ||
306 | self.last_surface_index = surface.index | 317 | self.last_surface_index = surface.index |
307 | 318 | ||
308 | Publisher.sendMessage('Load surface actor into viewer', actor) | 319 | Publisher.sendMessage('Load surface actor into viewer', actor) |
309 | 320 | ||
310 | Publisher.sendMessage('Update surface info in GUI', | 321 | Publisher.sendMessage('Update surface info in GUI', |
311 | - (surface.index, surface.name, | ||
312 | - surface.colour, surface.volume, | ||
313 | - surface.transparency)) | 322 | + (surface.index, surface.name, |
323 | + surface.colour, surface.volume, | ||
324 | + surface.area, surface.transparency)) | ||
314 | return surface.index | 325 | return surface.index |
315 | 326 | ||
316 | def OnCloseProject(self, pubsub_evt): | 327 | def OnCloseProject(self, pubsub_evt): |
@@ -329,9 +340,9 @@ class SurfaceManager(): | @@ -329,9 +340,9 @@ class SurfaceManager(): | ||
329 | proj = prj.Project() | 340 | proj = prj.Project() |
330 | surface = proj.surface_dict[index] | 341 | surface = proj.surface_dict[index] |
331 | Publisher.sendMessage('Update surface info in GUI', | 342 | Publisher.sendMessage('Update surface info in GUI', |
332 | - (index, surface.name, | ||
333 | - surface.colour, surface.volume, | ||
334 | - surface.transparency)) | 343 | + (index, surface.name, |
344 | + surface.colour, surface.volume, | ||
345 | + surface.area, surface.transparency)) | ||
335 | self.last_surface_index = index | 346 | self.last_surface_index = index |
336 | if surface.is_shown: | 347 | if surface.is_shown: |
337 | self.ShowActor(index, True) | 348 | self.ShowActor(index, True) |
@@ -377,8 +388,8 @@ class SurfaceManager(): | @@ -377,8 +388,8 @@ class SurfaceManager(): | ||
377 | # The following lines have to be here, otherwise all volumes disappear | 388 | # The following lines have to be here, otherwise all volumes disappear |
378 | Publisher.sendMessage('Update surface info in GUI', | 389 | Publisher.sendMessage('Update surface info in GUI', |
379 | (surface.index, surface.name, | 390 | (surface.index, surface.name, |
380 | - surface.colour, surface.volume, | ||
381 | - surface.transparency)) | 391 | + surface.colour, surface.volume, |
392 | + surface.area, surface.transparency)) | ||
382 | if not surface.is_shown: | 393 | if not surface.is_shown: |
383 | self.ShowActor(key, False) | 394 | self.ShowActor(key, False) |
384 | 395 | ||
@@ -727,7 +738,9 @@ class SurfaceManager(): | @@ -727,7 +738,9 @@ class SurfaceManager(): | ||
727 | # measured_polydata.ReleaseDataFlagOn() | 738 | # measured_polydata.ReleaseDataFlagOn() |
728 | measured_polydata.SetInputData(to_measure) | 739 | measured_polydata.SetInputData(to_measure) |
729 | volume = float(measured_polydata.GetVolume()) | 740 | volume = float(measured_polydata.GetVolume()) |
741 | + area = float(measured_polydata.GetSurfaceArea()) | ||
730 | surface.volume = volume | 742 | surface.volume = volume |
743 | + surface.area = area | ||
731 | self.last_surface_index = surface.index | 744 | self.last_surface_index = surface.index |
732 | del measured_polydata | 745 | del measured_polydata |
733 | del to_measure | 746 | del to_measure |
@@ -745,6 +758,7 @@ class SurfaceManager(): | @@ -745,6 +758,7 @@ class SurfaceManager(): | ||
745 | Publisher.sendMessage('Update surface info in GUI', | 758 | Publisher.sendMessage('Update surface info in GUI', |
746 | (surface.index, surface.name, | 759 | (surface.index, surface.name, |
747 | surface.colour, surface.volume, | 760 | surface.colour, surface.volume, |
761 | + surface.area, | ||
748 | surface.transparency)) | 762 | surface.transparency)) |
749 | 763 | ||
750 | #When you finalize the progress. The bar is cleaned. | 764 | #When you finalize the progress. The bar is cleaned. |
invesalius/gui/data_notebook.py
@@ -765,12 +765,14 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | @@ -765,12 +765,14 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | ||
765 | self.InsertColumn(0, "", wx.LIST_FORMAT_CENTER) | 765 | self.InsertColumn(0, "", wx.LIST_FORMAT_CENTER) |
766 | self.InsertColumn(1, _("Name")) | 766 | self.InsertColumn(1, _("Name")) |
767 | self.InsertColumn(2, _(u"Volume (mm³)")) | 767 | self.InsertColumn(2, _(u"Volume (mm³)")) |
768 | - self.InsertColumn(3, _("Transparency"), wx.LIST_FORMAT_RIGHT) | 768 | + self.InsertColumn(3, _(u"Area (mm²)")) |
769 | + self.InsertColumn(4, _("Transparency"), wx.LIST_FORMAT_RIGHT) | ||
769 | 770 | ||
770 | self.SetColumnWidth(0, 25) | 771 | self.SetColumnWidth(0, 25) |
771 | self.SetColumnWidth(1, 85) | 772 | self.SetColumnWidth(1, 85) |
772 | self.SetColumnWidth(2, 85) | 773 | self.SetColumnWidth(2, 85) |
773 | - self.SetColumnWidth(3, 80) | 774 | + self.SetColumnWidth(3, 85) |
775 | + self.SetColumnWidth(4, 80) | ||
774 | 776 | ||
775 | def __init_image_list(self): | 777 | def __init_image_list(self): |
776 | self.imagelist = wx.ImageList(16, 16) | 778 | self.imagelist = wx.ImageList(16, 16) |
@@ -830,7 +832,8 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | @@ -830,7 +832,8 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | ||
830 | name = pubsub_evt.data[1] | 832 | name = pubsub_evt.data[1] |
831 | colour = pubsub_evt.data[2] | 833 | colour = pubsub_evt.data[2] |
832 | volume = "%.3f"%pubsub_evt.data[3] | 834 | volume = "%.3f"%pubsub_evt.data[3] |
833 | - transparency = "%d%%"%(int(100*pubsub_evt.data[4])) | 835 | + area = "%.3f"%pubsub_evt.data[4] |
836 | + transparency = "%d%%"%(int(100*pubsub_evt.data[5])) | ||
834 | 837 | ||
835 | if index not in self.surface_list_index: | 838 | if index not in self.surface_list_index: |
836 | image = self.CreateColourBitmap(colour) | 839 | image = self.CreateColourBitmap(colour) |
@@ -840,25 +843,29 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | @@ -840,25 +843,29 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | ||
840 | self.surface_list_index[index] = image_index | 843 | self.surface_list_index[index] = image_index |
841 | 844 | ||
842 | if (index in index_list) and index_list: | 845 | if (index in index_list) and index_list: |
843 | - self.UpdateItemInfo(index, name, volume, transparency, colour) | 846 | + self.UpdateItemInfo(index, name, volume, area, transparency, colour) |
844 | else: | 847 | else: |
845 | - self.InsertNewItem(index, name, volume, transparency, colour) | 848 | + self.InsertNewItem(index, name, volume, area, transparency, colour) |
849 | + else: | ||
850 | + self.UpdateItemInfo(index, name, volume, area, transparency, colour) | ||
846 | 851 | ||
847 | def InsertNewItem(self, index=0, label="Surface 1", volume="0 mm3", | 852 | def InsertNewItem(self, index=0, label="Surface 1", volume="0 mm3", |
848 | - transparency="0%%", colour=None): | 853 | + area="0 mm2", transparency="0%%", colour=None): |
849 | self.InsertStringItem(index, "") | 854 | self.InsertStringItem(index, "") |
850 | self.SetStringItem(index, 1, label, | 855 | self.SetStringItem(index, 1, label, |
851 | imageId = self.surface_list_index[index]) | 856 | imageId = self.surface_list_index[index]) |
852 | self.SetStringItem(index, 2, volume) | 857 | self.SetStringItem(index, 2, volume) |
853 | - self.SetStringItem(index, 3, transparency) | 858 | + self.SetStringItem(index, 3, area) |
859 | + self.SetStringItem(index, 4, transparency) | ||
854 | self.SetItemImage(index, 1) | 860 | self.SetItemImage(index, 1) |
855 | 861 | ||
856 | def UpdateItemInfo(self, index=0, label="Surface 1", volume="0 mm3", | 862 | def UpdateItemInfo(self, index=0, label="Surface 1", volume="0 mm3", |
857 | - transparency="0%%", colour=None): | 863 | + area="0 mm2", transparency="0%%", colour=None): |
858 | self.SetStringItem(index, 1, label, | 864 | self.SetStringItem(index, 1, label, |
859 | imageId = self.surface_list_index[index]) | 865 | imageId = self.surface_list_index[index]) |
860 | self.SetStringItem(index, 2, volume) | 866 | self.SetStringItem(index, 2, volume) |
861 | - self.SetStringItem(index, 3, transparency) | 867 | + self.SetStringItem(index, 3, area) |
868 | + self.SetStringItem(index, 4, transparency) | ||
862 | self.SetItemImage(index, 1) | 869 | self.SetItemImage(index, 1) |
863 | 870 | ||
864 | def CreateColourBitmap(self, colour): | 871 | def CreateColourBitmap(self, colour): |
@@ -889,7 +896,7 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | @@ -889,7 +896,7 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | ||
889 | index and value. | 896 | index and value. |
890 | """ | 897 | """ |
891 | index, value = pubsub_evt.data | 898 | index, value = pubsub_evt.data |
892 | - self.SetStringItem(index, 3, "%d%%"%(int(value*100))) | 899 | + self.SetStringItem(index, 4, "%d%%"%(int(value*100))) |
893 | 900 | ||
894 | def EditSurfaceColour(self, pubsub_evt): | 901 | def EditSurfaceColour(self, pubsub_evt): |
895 | """ | 902 | """ |