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 | 124 | self.point_actor1 = None |
125 | 125 | self.point_actor2 = None |
126 | 126 | self.line_actor = None |
127 | + self.text_actor = None | |
127 | 128 | self.render = render |
128 | 129 | if not representation: |
129 | 130 | representation = CirclePointRepresentation() |
130 | 131 | self.representation = representation |
131 | 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 | 146 | def SetPoint1(self, x, y, z): |
134 | 147 | self.points.append((x, y, z)) |
135 | 148 | self.point_actor1 = self.representation.GetRepresentation(x, y, z) |
... | ... | @@ -197,6 +210,26 @@ class LinearMeasure(object): |
197 | 210 | self.line_actor.SetVisibility(v) |
198 | 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 | 234 | class AngularMeasure(object): |
202 | 235 | def __init__(self, render, colour=(1, 0, 0), representation=None): |
... | ... | @@ -207,12 +240,24 @@ class AngularMeasure(object): |
207 | 240 | self.point_actor2 = None |
208 | 241 | self.point_actor3 = None |
209 | 242 | self.line_actor = None |
243 | + self.text_actor = None | |
210 | 244 | self.render = render |
211 | 245 | if not representation: |
212 | 246 | representation = CirclePointRepresentation() |
213 | 247 | self.representation = representation |
214 | 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 | 261 | def SetPoint1(self, x, y, z): |
217 | 262 | self.points[0] = (x, y, z) |
218 | 263 | self.number_of_points = 1 |
... | ... | @@ -343,4 +388,26 @@ class AngularMeasure(object): |
343 | 388 | angle = math.degrees(math.acos(cos)) |
344 | 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 | 94 | self.measure_picker = vtk.vtkPropPicker() |
95 | 95 | #self.measure_picker.SetTolerance(0.005) |
96 | 96 | self.measures = [] |
97 | + | |
98 | + self._last_state = 0 | |
97 | 99 | |
98 | 100 | |
99 | 101 | def __bind_events(self): |
... | ... | @@ -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 | 316 | if state == const.STATE_WL: |
310 | 317 | self.on_wl = True |
311 | 318 | if self.raycasting_volume: |
... | ... | @@ -334,6 +341,8 @@ class Viewer(wx.Panel): |
334 | 341 | # Bind event |
335 | 342 | style.AddObserver(event,action[state][event]) |
336 | 343 | |
344 | + self._last_state = state | |
345 | + | |
337 | 346 | def OnSpinMove(self, evt, obj): |
338 | 347 | if (self.mouse_pressed): |
339 | 348 | evt.Spin() |
... | ... | @@ -615,37 +624,36 @@ class Viewer(wx.Panel): |
615 | 624 | x,y = self.interactor.GetEventPosition() |
616 | 625 | self.measure_picker.Pick(x, y, 0, self.ren) |
617 | 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 | 640 | def OnInsertAngularMeasurePoint(self, obj, evt): |
631 | 641 | print "Hey, you inserted a angular point" |
632 | 642 | x,y = self.interactor.GetEventPosition() |
633 | 643 | self.measure_picker.Pick(x, y, 0, self.ren) |
634 | 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 | 659 | class SlicePlane: | ... | ... |