Commit 41d183fe015e1b8add1ae88100f01bf92d510847
Exists in
master
and in
57 other branches
Merge pull request #17 from tfmoraes/measure_spacing
Measure spacing
Showing
6 changed files
with
82 additions
and
14 deletions
Show diff stats
invesalius/constants.py
invesalius/control.py
| ... | ... | @@ -405,7 +405,7 @@ class Controller(): |
| 405 | 405 | (mask_name, thresh, colour)) |
| 406 | 406 | |
| 407 | 407 | Publisher.sendMessage('Load measurement dict', |
| 408 | - proj.measurement_dict) | |
| 408 | + (proj.measurement_dict, self.Slice.spacing)) | |
| 409 | 409 | |
| 410 | 410 | Publisher.sendMessage(('Set scroll position', 'AXIAL'),proj.matrix_shape[0]/2) |
| 411 | 411 | Publisher.sendMessage(('Set scroll position', 'SAGITAL'),proj.matrix_shape[1]/2) | ... | ... |
invesalius/data/measures.py
| ... | ... | @@ -21,6 +21,7 @@ LOCATION = {const.SURFACE: _(u"3D"), |
| 21 | 21 | const.SAGITAL: _(u"Sagittal") |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | + | |
| 24 | 25 | class MeasurementManager(object): |
| 25 | 26 | """ |
| 26 | 27 | A class to manage the use (Addition, remotion and visibility) from |
| ... | ... | @@ -39,13 +40,31 @@ class MeasurementManager(object): |
| 39 | 40 | Publisher.subscribe(self._load_measurements, "Load measurement dict") |
| 40 | 41 | |
| 41 | 42 | def _load_measurements(self, pubsub_evt): |
| 42 | - dict = pubsub_evt.data | |
| 43 | + try: | |
| 44 | + dict, spacing = pubsub_evt.data | |
| 45 | + except ValueError: | |
| 46 | + dict = pubsub_evt.data | |
| 47 | + spacing = 1.0, 1.0, 1.0 | |
| 43 | 48 | for i in dict: |
| 44 | 49 | m = dict[i] |
| 50 | + | |
| 51 | + if m.location == const.AXIAL: | |
| 52 | + radius = min(spacing[1], spacing[2]) * const.PROP_MEASURE | |
| 53 | + | |
| 54 | + elif m.location == const.CORONAL: | |
| 55 | + radius = min(spacing[0], spacing[1]) * const.PROP_MEASURE | |
| 56 | + | |
| 57 | + elif m.location == const.SAGITAL: | |
| 58 | + radius = min(spacing[1], spacing[2]) * const.PROP_MEASURE | |
| 59 | + | |
| 60 | + else: | |
| 61 | + radius = min(spacing) * const.PROP_MEASURE | |
| 62 | + | |
| 63 | + representation = CirclePointRepresentation(m.colour, radius) | |
| 45 | 64 | if m.type == const.LINEAR: |
| 46 | - mr = LinearMeasure(m.colour) | |
| 65 | + mr = LinearMeasure(m.colour, representation) | |
| 47 | 66 | else: |
| 48 | - mr = AngularMeasure(m.colour) | |
| 67 | + mr = AngularMeasure(m.colour, representation) | |
| 49 | 68 | self.current = (m, mr) |
| 50 | 69 | self.measures.append(self.current) |
| 51 | 70 | for point in m.points: |
| ... | ... | @@ -66,10 +85,23 @@ class MeasurementManager(object): |
| 66 | 85 | position = pubsub_evt.data[0] |
| 67 | 86 | type = pubsub_evt.data[1] # Linear or Angular |
| 68 | 87 | location = pubsub_evt.data[2] # 3D, AXIAL, SAGITAL, CORONAL |
| 69 | - try: | |
| 70 | - slice_number = pubsub_evt.data[3] | |
| 71 | - except IndexError: | |
| 88 | + | |
| 89 | + if location == const.SURFACE: | |
| 72 | 90 | slice_number = 0 |
| 91 | + try: | |
| 92 | + radius = pubsub_evt.data[3] | |
| 93 | + except IndexError: | |
| 94 | + radius = const.PROP_MEASURE | |
| 95 | + else: | |
| 96 | + try: | |
| 97 | + slice_number = pubsub_evt.data[3] | |
| 98 | + except IndexError: | |
| 99 | + slice_number = 0 | |
| 100 | + | |
| 101 | + try: | |
| 102 | + radius = pubsub_evt.data[4] | |
| 103 | + except IndexError: | |
| 104 | + radius = const.PROP_MEASURE | |
| 73 | 105 | |
| 74 | 106 | to_remove = False |
| 75 | 107 | if self.current is None: |
| ... | ... | @@ -95,10 +127,11 @@ class MeasurementManager(object): |
| 95 | 127 | m.location = location |
| 96 | 128 | m.slice_number = slice_number |
| 97 | 129 | m.type = type |
| 130 | + representation = CirclePointRepresentation(m.colour, radius) | |
| 98 | 131 | if type == const.LINEAR: |
| 99 | - mr = LinearMeasure(m.colour) | |
| 132 | + mr = LinearMeasure(m.colour, representation) | |
| 100 | 133 | else: |
| 101 | - mr = AngularMeasure(m.colour) | |
| 134 | + mr = AngularMeasure(m.colour, representation) | |
| 102 | 135 | if to_remove: |
| 103 | 136 | print "---To REMOVE" |
| 104 | 137 | actors = self.current[1].GetActors() | ... | ... |
invesalius/data/styles.py
| ... | ... | @@ -271,6 +271,17 @@ class LinearMeasureInteractorStyle(DefaultInteractorStyle): |
| 271 | 271 | self.orientation = viewer.orientation |
| 272 | 272 | self.slice_data = viewer.slice_data |
| 273 | 273 | |
| 274 | + spacing = self.slice_data.actor.GetInput().GetSpacing() | |
| 275 | + | |
| 276 | + if self.orientation == "AXIAL": | |
| 277 | + self.radius = min(spacing[1], spacing[2]) * 0.8 | |
| 278 | + | |
| 279 | + elif self.orientation == 'CORONAL': | |
| 280 | + self.radius = min(spacing[0], spacing[1]) * 0.8 | |
| 281 | + | |
| 282 | + elif self.orientation == 'SAGITAL': | |
| 283 | + self.radius = min(spacing[1], spacing[2]) * 0.8 | |
| 284 | + | |
| 274 | 285 | self.picker = vtk.vtkCellPicker() |
| 275 | 286 | |
| 276 | 287 | self.AddObserver("LeftButtonPressEvent", self.OnInsertLinearMeasurePoint) |
| ... | ... | @@ -286,7 +297,7 @@ class LinearMeasureInteractorStyle(DefaultInteractorStyle): |
| 286 | 297 | Publisher.sendMessage("Add measurement point", |
| 287 | 298 | ((x, y,z), const.LINEAR, |
| 288 | 299 | ORIENTATIONS[self.orientation], |
| 289 | - slice_number)) | |
| 300 | + slice_number, self.radius)) | |
| 290 | 301 | self.viewer.interactor.Render() |
| 291 | 302 | |
| 292 | 303 | |
| ... | ... | @@ -301,6 +312,17 @@ class AngularMeasureInteractorStyle(DefaultInteractorStyle): |
| 301 | 312 | self.orientation = viewer.orientation |
| 302 | 313 | self.slice_data = viewer.slice_data |
| 303 | 314 | |
| 315 | + spacing = self.slice_data.actor.GetInput().GetSpacing() | |
| 316 | + | |
| 317 | + if self.orientation == "AXIAL": | |
| 318 | + self.radius = min(spacing[1], spacing[2]) * 0.8 | |
| 319 | + | |
| 320 | + elif self.orientation == 'CORONAL': | |
| 321 | + self.radius = min(spacing[0], spacing[1]) * 0.8 | |
| 322 | + | |
| 323 | + elif self.orientation == 'SAGITAL': | |
| 324 | + self.radius = min(spacing[1], spacing[2]) * 0.8 | |
| 325 | + | |
| 304 | 326 | self.picker = vtk.vtkCellPicker() |
| 305 | 327 | |
| 306 | 328 | self.AddObserver("LeftButtonPressEvent", self.OnInsertAngularMeasurePoint) |
| ... | ... | @@ -316,7 +338,7 @@ class AngularMeasureInteractorStyle(DefaultInteractorStyle): |
| 316 | 338 | Publisher.sendMessage("Add measurement point", |
| 317 | 339 | ((x, y,z), const.ANGULAR, |
| 318 | 340 | ORIENTATIONS[self.orientation], |
| 319 | - slice_number)) | |
| 341 | + slice_number, self.radius)) | |
| 320 | 342 | self.viewer.interactor.Render() |
| 321 | 343 | |
| 322 | 344 | ... | ... |
invesalius/data/viewer_volume.py
| ... | ... | @@ -37,6 +37,8 @@ import utils |
| 37 | 37 | |
| 38 | 38 | from data import measures |
| 39 | 39 | |
| 40 | +PROP_MEASURE = 0.8 | |
| 41 | + | |
| 40 | 42 | class Viewer(wx.Panel): |
| 41 | 43 | def __init__(self, parent): |
| 42 | 44 | wx.Panel.__init__(self, parent, size=wx.Size(320, 320)) |
| ... | ... | @@ -815,6 +817,9 @@ class Viewer(wx.Panel): |
| 815 | 817 | x,y = self.interactor.GetEventPosition() |
| 816 | 818 | self.measure_picker.Pick(x, y, 0, self.ren) |
| 817 | 819 | x, y, z = self.measure_picker.GetPickPosition() |
| 820 | + | |
| 821 | + proj = prj.Project() | |
| 822 | + radius = min(proj.spacing) * PROP_MEASURE | |
| 818 | 823 | if self.measure_picker.GetActor(): |
| 819 | 824 | # if not self.measures or self.measures[-1].IsComplete(): |
| 820 | 825 | # m = measures.LinearMeasure(self.ren) |
| ... | ... | @@ -827,7 +832,7 @@ class Viewer(wx.Panel): |
| 827 | 832 | # Publisher.sendMessage("Add measure to list", |
| 828 | 833 | # (u"3D", _(u"%.3f mm" % m.GetValue()))) |
| 829 | 834 | Publisher.sendMessage("Add measurement point", |
| 830 | - ((x, y,z), const.LINEAR, const.SURFACE)) | |
| 835 | + ((x, y,z), const.LINEAR, const.SURFACE, radius)) | |
| 831 | 836 | self.interactor.Render() |
| 832 | 837 | |
| 833 | 838 | def OnInsertAngularMeasurePoint(self, obj, evt): |
| ... | ... | @@ -835,6 +840,9 @@ class Viewer(wx.Panel): |
| 835 | 840 | x,y = self.interactor.GetEventPosition() |
| 836 | 841 | self.measure_picker.Pick(x, y, 0, self.ren) |
| 837 | 842 | x, y, z = self.measure_picker.GetPickPosition() |
| 843 | + | |
| 844 | + proj = prj.Project() | |
| 845 | + radius = min(proj.spacing) * PROP_MEASURE | |
| 838 | 846 | if self.measure_picker.GetActor(): |
| 839 | 847 | # if not self.measures or self.measures[-1].IsComplete(): |
| 840 | 848 | # m = measures.AngularMeasure(self.ren) |
| ... | ... | @@ -856,7 +864,7 @@ class Viewer(wx.Panel): |
| 856 | 864 | # type_, location, |
| 857 | 865 | # value)) |
| 858 | 866 | Publisher.sendMessage("Add measurement point", |
| 859 | - ((x, y,z), const.ANGULAR, const.SURFACE)) | |
| 867 | + ((x, y,z), const.ANGULAR, const.SURFACE, radius)) | |
| 860 | 868 | self.interactor.Render() |
| 861 | 869 | |
| 862 | 870 | def Reposition3DPlane(self, evt_pubsub): | ... | ... |
invesalius/gui/data_notebook.py
| ... | ... | @@ -1064,7 +1064,10 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): |
| 1064 | 1064 | (index, visibility)) |
| 1065 | 1065 | |
| 1066 | 1066 | def OnLoadData(self, pubsub_evt): |
| 1067 | - items_dict = pubsub_evt.data | |
| 1067 | + try: | |
| 1068 | + items_dict, spacing = pubsub_evt.data | |
| 1069 | + except ValueError: | |
| 1070 | + items_dict = pubsub_evt.data | |
| 1068 | 1071 | for i in items_dict: |
| 1069 | 1072 | m = items_dict[i] |
| 1070 | 1073 | image = self.CreateColourBitmap(m.colour) | ... | ... |