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) | ... | ... |