Commit 879f747a87186f829865f09f26e530016e21897d
1 parent
a524aa3a
Exists in
master
and in
6 other branches
ENH: Facilities to work with measures
Showing
2 changed files
with
100 additions
and
25 deletions
Show diff stats
invesalius/data/measures.py
@@ -124,12 +124,25 @@ class LinearMeasure(object): | @@ -124,12 +124,25 @@ class LinearMeasure(object): | ||
124 | self.point_actor1 = None | 124 | self.point_actor1 = None |
125 | self.point_actor2 = None | 125 | self.point_actor2 = None |
126 | self.line_actor = None | 126 | self.line_actor = None |
127 | + self.text_actor = None | ||
127 | self.render = render | 128 | self.render = render |
128 | if not representation: | 129 | if not representation: |
129 | representation = CirclePointRepresentation() | 130 | representation = CirclePointRepresentation() |
130 | self.representation = representation | 131 | self.representation = representation |
131 | print colour | 132 | print colour |
132 | 133 | ||
134 | + def IsComplete(self): | ||
135 | + """ | ||
136 | + Is this measure complete? | ||
137 | + """ | ||
138 | + return not self.point_actor2 is None | ||
139 | + | ||
140 | + def AddPoint(self, x, y, z): | ||
141 | + if not self.point_actor1: | ||
142 | + self.SetPoint1(x, y, z) | ||
143 | + elif not self.point_actor2: | ||
144 | + self.SetPoint2(x, y, z) | ||
145 | + | ||
133 | def SetPoint1(self, x, y, z): | 146 | def SetPoint1(self, x, y, z): |
134 | self.points.append((x, y, z)) | 147 | self.points.append((x, y, z)) |
135 | self.point_actor1 = self.representation.GetRepresentation(x, y, z) | 148 | self.point_actor1 = self.representation.GetRepresentation(x, y, z) |
@@ -197,6 +210,26 @@ class LinearMeasure(object): | @@ -197,6 +210,26 @@ class LinearMeasure(object): | ||
197 | self.line_actor.SetVisibility(v) | 210 | self.line_actor.SetVisibility(v) |
198 | self.text_actor.SetVisibility(v) | 211 | self.text_actor.SetVisibility(v) |
199 | 212 | ||
213 | + def Remove(self): | ||
214 | + if self.point_actor1: | ||
215 | + self.render.RemoveActor(self.point_actor1) | ||
216 | + del self.point_actor1 | ||
217 | + | ||
218 | + if self.point_actor2: | ||
219 | + self.render.RemoveActor(self.point_actor2) | ||
220 | + del self.point_actor2 | ||
221 | + | ||
222 | + if self.line_actor: | ||
223 | + self.render.RemoveActor(self.line_actor) | ||
224 | + del self.line_actor | ||
225 | + | ||
226 | + if self.text_actor: | ||
227 | + self.render.RemoveActor(self.text_actor) | ||
228 | + del self.text_actor | ||
229 | + | ||
230 | + def __del__(self): | ||
231 | + self.Remove() | ||
232 | + | ||
200 | 233 | ||
201 | class AngularMeasure(object): | 234 | class AngularMeasure(object): |
202 | def __init__(self, render, colour=(1, 0, 0), representation=None): | 235 | def __init__(self, render, colour=(1, 0, 0), representation=None): |
@@ -207,12 +240,24 @@ class AngularMeasure(object): | @@ -207,12 +240,24 @@ class AngularMeasure(object): | ||
207 | self.point_actor2 = None | 240 | self.point_actor2 = None |
208 | self.point_actor3 = None | 241 | self.point_actor3 = None |
209 | self.line_actor = None | 242 | self.line_actor = None |
243 | + self.text_actor = None | ||
210 | self.render = render | 244 | self.render = render |
211 | if not representation: | 245 | if not representation: |
212 | representation = CirclePointRepresentation() | 246 | representation = CirclePointRepresentation() |
213 | self.representation = representation | 247 | self.representation = representation |
214 | print colour | 248 | print colour |
215 | 249 | ||
250 | + def IsComplete(self): | ||
251 | + return not self.point_actor3 is None | ||
252 | + | ||
253 | + def AddPoint(self, x, y, z): | ||
254 | + if not self.point_actor1: | ||
255 | + self.SetPoint1(x, y, z) | ||
256 | + elif not self.point_actor2: | ||
257 | + self.SetPoint2(x, y, z) | ||
258 | + elif not self.point_actor3: | ||
259 | + self.SetPoint3(x, y, z) | ||
260 | + | ||
216 | def SetPoint1(self, x, y, z): | 261 | def SetPoint1(self, x, y, z): |
217 | self.points[0] = (x, y, z) | 262 | self.points[0] = (x, y, z) |
218 | self.number_of_points = 1 | 263 | self.number_of_points = 1 |
@@ -343,4 +388,26 @@ class AngularMeasure(object): | @@ -343,4 +388,26 @@ class AngularMeasure(object): | ||
343 | angle = math.degrees(math.acos(cos)) | 388 | angle = math.degrees(math.acos(cos)) |
344 | return angle | 389 | return angle |
345 | 390 | ||
391 | + def Remove(self): | ||
392 | + if self.point_actor1: | ||
393 | + self.render.RemoveActor(self.point_actor1) | ||
394 | + del self.point_actor1 | ||
395 | + | ||
396 | + if self.point_actor2: | ||
397 | + self.render.RemoveActor(self.point_actor2) | ||
398 | + del self.point_actor2 | ||
399 | + | ||
400 | + if self.point_actor3: | ||
401 | + self.render.RemoveActor(self.point_actor3) | ||
402 | + del self.point_actor3 | ||
403 | + | ||
404 | + if self.line_actor: | ||
405 | + self.render.RemoveActor(self.line_actor) | ||
406 | + del self.line_actor | ||
407 | + | ||
408 | + if self.text_actor: | ||
409 | + self.render.RemoveActor(self.text_actor) | ||
410 | + del self.text_actor | ||
346 | 411 | ||
412 | + def __del__(self): | ||
413 | + self.Remove() |
invesalius/data/viewer_volume.py
@@ -94,6 +94,8 @@ class Viewer(wx.Panel): | @@ -94,6 +94,8 @@ class Viewer(wx.Panel): | ||
94 | self.measure_picker = vtk.vtkPropPicker() | 94 | self.measure_picker = vtk.vtkPropPicker() |
95 | #self.measure_picker.SetTolerance(0.005) | 95 | #self.measure_picker.SetTolerance(0.005) |
96 | self.measures = [] | 96 | self.measures = [] |
97 | + | ||
98 | + self._last_state = 0 | ||
97 | 99 | ||
98 | 100 | ||
99 | def __bind_events(self): | 101 | def __bind_events(self): |
@@ -306,6 +308,11 @@ class Viewer(wx.Panel): | @@ -306,6 +308,11 @@ class Viewer(wx.Panel): | ||
306 | } | 308 | } |
307 | } | 309 | } |
308 | 310 | ||
311 | + if self._last_state in (const.STATE_MEASURE_DISTANCE, | ||
312 | + const.STATE_MEASURE_ANGLE): | ||
313 | + if self.measures and not self.measures[-1].text_actor: | ||
314 | + del self.measures[-1] | ||
315 | + | ||
309 | if state == const.STATE_WL: | 316 | if state == const.STATE_WL: |
310 | self.on_wl = True | 317 | self.on_wl = True |
311 | if self.raycasting_volume: | 318 | if self.raycasting_volume: |
@@ -334,6 +341,8 @@ class Viewer(wx.Panel): | @@ -334,6 +341,8 @@ class Viewer(wx.Panel): | ||
334 | # Bind event | 341 | # Bind event |
335 | style.AddObserver(event,action[state][event]) | 342 | style.AddObserver(event,action[state][event]) |
336 | 343 | ||
344 | + self._last_state = state | ||
345 | + | ||
337 | def OnSpinMove(self, evt, obj): | 346 | def OnSpinMove(self, evt, obj): |
338 | if (self.mouse_pressed): | 347 | if (self.mouse_pressed): |
339 | evt.Spin() | 348 | evt.Spin() |
@@ -615,37 +624,36 @@ class Viewer(wx.Panel): | @@ -615,37 +624,36 @@ class Viewer(wx.Panel): | ||
615 | x,y = self.interactor.GetEventPosition() | 624 | x,y = self.interactor.GetEventPosition() |
616 | self.measure_picker.Pick(x, y, 0, self.ren) | 625 | self.measure_picker.Pick(x, y, 0, self.ren) |
617 | x, y, z = self.measure_picker.GetPickPosition() | 626 | x, y, z = self.measure_picker.GetPickPosition() |
618 | -# if self.measure_picker.GetPointId() != -1: | ||
619 | - if not self.measures or self.measures[-1].point_actor2: | ||
620 | - m = measures.LinearMeasure(self.ren) | ||
621 | - m.SetPoint1(x, y, z) | ||
622 | - self.measures.append(m) | ||
623 | - else: | ||
624 | - m = self.measures[-1] | ||
625 | - m.SetPoint2(x, y, z) | ||
626 | - ps.Publisher().sendMessage("Add measure to list", | ||
627 | - ("3D", _("%.3f mm3" % m.GetValue()))) | ||
628 | - self.interactor.Render() | 627 | + if self.measure_picker.GetActor(): |
628 | + if not self.measures or self.measures[-1].IsComplete(): | ||
629 | + m = measures.LinearMeasure(self.ren) | ||
630 | + m.AddPoint(x, y, z) | ||
631 | + self.measures.append(m) | ||
632 | + else: | ||
633 | + m = self.measures[-1] | ||
634 | + m.AddPoint(x, y, z) | ||
635 | + if m.IsComplete(): | ||
636 | + ps.Publisher().sendMessage("Add measure to list", | ||
637 | + ("3D", _("%.3f mm3" % m.GetValue()))) | ||
638 | + self.interactor.Render() | ||
629 | 639 | ||
630 | def OnInsertAngularMeasurePoint(self, obj, evt): | 640 | def OnInsertAngularMeasurePoint(self, obj, evt): |
631 | print "Hey, you inserted a angular point" | 641 | print "Hey, you inserted a angular point" |
632 | x,y = self.interactor.GetEventPosition() | 642 | x,y = self.interactor.GetEventPosition() |
633 | self.measure_picker.Pick(x, y, 0, self.ren) | 643 | self.measure_picker.Pick(x, y, 0, self.ren) |
634 | x, y, z = self.measure_picker.GetPickPosition() | 644 | x, y, z = self.measure_picker.GetPickPosition() |
635 | -# if self.measure_picker.GetPointId() != -1: | ||
636 | - if not self.measures or self.measures[-1].point_actor3: | ||
637 | - m = measures.AngularMeasure(self.ren) | ||
638 | - m.SetPoint1(x, y, z) | ||
639 | - self.measures.append(m) | ||
640 | - elif not self.measures[-1].point_actor2: | ||
641 | - m = self.measures[-1] | ||
642 | - m.SetPoint2(x, y, z) | ||
643 | - else: | ||
644 | - m = self.measures[-1] | ||
645 | - m.SetPoint3(x, y, z) | ||
646 | - ps.Publisher().sendMessage("Add measure to list", | ||
647 | - ("3D", _("%.3f" % m.GetValue()))) | ||
648 | - self.interactor.Render() | 645 | + if self.measure_picker.GetActor(): |
646 | + if not self.measures or self.measures[-1].IsComplete(): | ||
647 | + m = measures.AngularMeasure(self.ren) | ||
648 | + m.AddPoint(x, y, z) | ||
649 | + self.measures.append(m) | ||
650 | + else: | ||
651 | + m = self.measures[-1] | ||
652 | + m.AddPoint(x, y, z) | ||
653 | + if m.IsComplete(): | ||
654 | + ps.Publisher().sendMessage("Add measure to list", | ||
655 | + ("3D", _("%.3f" % m.GetValue()))) | ||
656 | + self.interactor.Render() | ||
649 | 657 | ||
650 | 658 | ||
651 | class SlicePlane: | 659 | class SlicePlane: |