Commit 41d183fe015e1b8add1ae88100f01bf92d510847

Authored by Thiago Franco de Moraes
2 parents 8d9b272f 855d18d9

Merge pull request #17 from tfmoraes/measure_spacing

Measure spacing
invesalius/constants.py
... ... @@ -38,6 +38,8 @@ DEFAULT_MEASURE_BG_COLOUR = (250/255.0, 247/255.0, 218/255.0)
38 38 DEFAULT_MEASURE_RADIUS = 1
39 39 DEFAULT_MEASURE_TYPE = MEASURE_LINEAR
40 40  
  41 +PROP_MEASURE = 0.8
  42 +
41 43  
42 44 STEREO_OFF = _(" Off")
43 45 STEREO_RED_BLUE = _("Red-blue")
... ...
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)
... ...