From 855d18d945af1d79bb186147ab6efd985833ad80 Mon Sep 17 00:00:00 2001 From: Thiago Franco de Moraes Date: Tue, 16 Apr 2013 11:26:28 -0300 Subject: [PATCH] Makes the measure mark proportional to image spacing --- invesalius/constants.py | 2 ++ invesalius/control.py | 2 +- invesalius/data/measures.py | 49 +++++++++++++++++++++++++++++++++++++++++-------- invesalius/data/styles.py | 26 ++++++++++++++++++++++++-- invesalius/data/viewer_volume.py | 12 ++++++++++-- invesalius/gui/data_notebook.py | 5 ++++- 6 files changed, 82 insertions(+), 14 deletions(-) diff --git a/invesalius/constants.py b/invesalius/constants.py index 3dfc5df..b239b3a 100644 --- a/invesalius/constants.py +++ b/invesalius/constants.py @@ -38,6 +38,8 @@ DEFAULT_MEASURE_BG_COLOUR = (250/255.0, 247/255.0, 218/255.0) DEFAULT_MEASURE_RADIUS = 1 DEFAULT_MEASURE_TYPE = MEASURE_LINEAR +PROP_MEASURE = 0.8 + STEREO_OFF = _(" Off") STEREO_RED_BLUE = _("Red-blue") diff --git a/invesalius/control.py b/invesalius/control.py index 74a089e..2e6d866 100644 --- a/invesalius/control.py +++ b/invesalius/control.py @@ -405,7 +405,7 @@ class Controller(): (mask_name, thresh, colour)) Publisher.sendMessage('Load measurement dict', - proj.measurement_dict) + (proj.measurement_dict, self.Slice.spacing)) Publisher.sendMessage(('Set scroll position', 'AXIAL'),proj.matrix_shape[0]/2) Publisher.sendMessage(('Set scroll position', 'SAGITAL'),proj.matrix_shape[1]/2) diff --git a/invesalius/data/measures.py b/invesalius/data/measures.py index e1e0d09..34f5318 100644 --- a/invesalius/data/measures.py +++ b/invesalius/data/measures.py @@ -21,6 +21,7 @@ LOCATION = {const.SURFACE: _(u"3D"), const.SAGITAL: _(u"Sagittal") } + class MeasurementManager(object): """ A class to manage the use (Addition, remotion and visibility) from @@ -39,13 +40,31 @@ class MeasurementManager(object): Publisher.subscribe(self._load_measurements, "Load measurement dict") def _load_measurements(self, pubsub_evt): - dict = pubsub_evt.data + try: + dict, spacing = pubsub_evt.data + except ValueError: + dict = pubsub_evt.data + spacing = 1.0, 1.0, 1.0 for i in dict: m = dict[i] + + if m.location == const.AXIAL: + radius = min(spacing[1], spacing[2]) * const.PROP_MEASURE + + elif m.location == const.CORONAL: + radius = min(spacing[0], spacing[1]) * const.PROP_MEASURE + + elif m.location == const.SAGITAL: + radius = min(spacing[1], spacing[2]) * const.PROP_MEASURE + + else: + radius = min(spacing) * const.PROP_MEASURE + + representation = CirclePointRepresentation(m.colour, radius) if m.type == const.LINEAR: - mr = LinearMeasure(m.colour) + mr = LinearMeasure(m.colour, representation) else: - mr = AngularMeasure(m.colour) + mr = AngularMeasure(m.colour, representation) self.current = (m, mr) self.measures.append(self.current) for point in m.points: @@ -66,10 +85,23 @@ class MeasurementManager(object): position = pubsub_evt.data[0] type = pubsub_evt.data[1] # Linear or Angular location = pubsub_evt.data[2] # 3D, AXIAL, SAGITAL, CORONAL - try: - slice_number = pubsub_evt.data[3] - except IndexError: + + if location == const.SURFACE: slice_number = 0 + try: + radius = pubsub_evt.data[3] + except IndexError: + radius = const.PROP_MEASURE + else: + try: + slice_number = pubsub_evt.data[3] + except IndexError: + slice_number = 0 + + try: + radius = pubsub_evt.data[4] + except IndexError: + radius = const.PROP_MEASURE to_remove = False if self.current is None: @@ -95,10 +127,11 @@ class MeasurementManager(object): m.location = location m.slice_number = slice_number m.type = type + representation = CirclePointRepresentation(m.colour, radius) if type == const.LINEAR: - mr = LinearMeasure(m.colour) + mr = LinearMeasure(m.colour, representation) else: - mr = AngularMeasure(m.colour) + mr = AngularMeasure(m.colour, representation) if to_remove: print "---To REMOVE" actors = self.current[1].GetActors() diff --git a/invesalius/data/styles.py b/invesalius/data/styles.py index 569e268..c7c7bb0 100644 --- a/invesalius/data/styles.py +++ b/invesalius/data/styles.py @@ -271,6 +271,17 @@ class LinearMeasureInteractorStyle(DefaultInteractorStyle): self.orientation = viewer.orientation self.slice_data = viewer.slice_data + spacing = self.slice_data.actor.GetInput().GetSpacing() + + if self.orientation == "AXIAL": + self.radius = min(spacing[1], spacing[2]) * 0.8 + + elif self.orientation == 'CORONAL': + self.radius = min(spacing[0], spacing[1]) * 0.8 + + elif self.orientation == 'SAGITAL': + self.radius = min(spacing[1], spacing[2]) * 0.8 + self.picker = vtk.vtkCellPicker() self.AddObserver("LeftButtonPressEvent", self.OnInsertLinearMeasurePoint) @@ -286,7 +297,7 @@ class LinearMeasureInteractorStyle(DefaultInteractorStyle): Publisher.sendMessage("Add measurement point", ((x, y,z), const.LINEAR, ORIENTATIONS[self.orientation], - slice_number)) + slice_number, self.radius)) self.viewer.interactor.Render() @@ -301,6 +312,17 @@ class AngularMeasureInteractorStyle(DefaultInteractorStyle): self.orientation = viewer.orientation self.slice_data = viewer.slice_data + spacing = self.slice_data.actor.GetInput().GetSpacing() + + if self.orientation == "AXIAL": + self.radius = min(spacing[1], spacing[2]) * 0.8 + + elif self.orientation == 'CORONAL': + self.radius = min(spacing[0], spacing[1]) * 0.8 + + elif self.orientation == 'SAGITAL': + self.radius = min(spacing[1], spacing[2]) * 0.8 + self.picker = vtk.vtkCellPicker() self.AddObserver("LeftButtonPressEvent", self.OnInsertAngularMeasurePoint) @@ -316,7 +338,7 @@ class AngularMeasureInteractorStyle(DefaultInteractorStyle): Publisher.sendMessage("Add measurement point", ((x, y,z), const.ANGULAR, ORIENTATIONS[self.orientation], - slice_number)) + slice_number, self.radius)) self.viewer.interactor.Render() diff --git a/invesalius/data/viewer_volume.py b/invesalius/data/viewer_volume.py index 481222b..c40691b 100755 --- a/invesalius/data/viewer_volume.py +++ b/invesalius/data/viewer_volume.py @@ -37,6 +37,8 @@ import utils from data import measures +PROP_MEASURE = 0.8 + class Viewer(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent, size=wx.Size(320, 320)) @@ -815,6 +817,9 @@ class Viewer(wx.Panel): x,y = self.interactor.GetEventPosition() self.measure_picker.Pick(x, y, 0, self.ren) x, y, z = self.measure_picker.GetPickPosition() + + proj = prj.Project() + radius = min(proj.spacing) * PROP_MEASURE if self.measure_picker.GetActor(): # if not self.measures or self.measures[-1].IsComplete(): # m = measures.LinearMeasure(self.ren) @@ -827,7 +832,7 @@ class Viewer(wx.Panel): # Publisher.sendMessage("Add measure to list", # (u"3D", _(u"%.3f mm" % m.GetValue()))) Publisher.sendMessage("Add measurement point", - ((x, y,z), const.LINEAR, const.SURFACE)) + ((x, y,z), const.LINEAR, const.SURFACE, radius)) self.interactor.Render() def OnInsertAngularMeasurePoint(self, obj, evt): @@ -835,6 +840,9 @@ class Viewer(wx.Panel): x,y = self.interactor.GetEventPosition() self.measure_picker.Pick(x, y, 0, self.ren) x, y, z = self.measure_picker.GetPickPosition() + + proj = prj.Project() + radius = min(proj.spacing) * PROP_MEASURE if self.measure_picker.GetActor(): # if not self.measures or self.measures[-1].IsComplete(): # m = measures.AngularMeasure(self.ren) @@ -856,7 +864,7 @@ class Viewer(wx.Panel): # type_, location, # value)) Publisher.sendMessage("Add measurement point", - ((x, y,z), const.ANGULAR, const.SURFACE)) + ((x, y,z), const.ANGULAR, const.SURFACE, radius)) self.interactor.Render() def Reposition3DPlane(self, evt_pubsub): diff --git a/invesalius/gui/data_notebook.py b/invesalius/gui/data_notebook.py index 7344c74..c0c0890 100644 --- a/invesalius/gui/data_notebook.py +++ b/invesalius/gui/data_notebook.py @@ -1064,7 +1064,10 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): (index, visibility)) def OnLoadData(self, pubsub_evt): - items_dict = pubsub_evt.data + try: + items_dict, spacing = pubsub_evt.data + except ValueError: + items_dict = pubsub_evt.data for i in items_dict: m = items_dict[i] image = self.CreateColourBitmap(m.colour) -- libgit2 0.21.2