Commit 2b068431df83e6ff48fe062236a6338bd3f44c6a
1 parent
e5349ae2
Exists in
measure_improvements
Moving measure points
Showing
3 changed files
with
133 additions
and
42 deletions
Show diff stats
invesalius/data/measures.py
@@ -22,6 +22,12 @@ LOCATION = {const.SURFACE: _(u"3D"), | @@ -22,6 +22,12 @@ LOCATION = {const.SURFACE: _(u"3D"), | ||
22 | const.SAGITAL: _(u"Sagittal") | 22 | const.SAGITAL: _(u"Sagittal") |
23 | } | 23 | } |
24 | 24 | ||
25 | +map_locations = { | ||
26 | + "3D": const.SURFACE, | ||
27 | + "AXIAL": const.AXIAL, | ||
28 | + "CORONAL": const.CORONAL, | ||
29 | + "SAGITAL": const.SAGITAL, | ||
30 | +} | ||
25 | 31 | ||
26 | class MeasureData: | 32 | class MeasureData: |
27 | """ | 33 | """ |
@@ -51,6 +57,9 @@ class MeasureData: | @@ -51,6 +57,9 @@ class MeasureData: | ||
51 | def __len__(self): | 57 | def __len__(self): |
52 | return len(self._list_measures) | 58 | return len(self._list_measures) |
53 | 59 | ||
60 | + def __getitem__(self, key): | ||
61 | + return self.measures[map_locations[key]] | ||
62 | + | ||
54 | 63 | ||
55 | class MeasurementManager(object): | 64 | class MeasurementManager(object): |
56 | """ | 65 | """ |
@@ -102,8 +111,8 @@ class MeasurementManager(object): | @@ -102,8 +111,8 @@ class MeasurementManager(object): | ||
102 | for point in m.points: | 111 | for point in m.points: |
103 | x, y, z = point | 112 | x, y, z = point |
104 | actors = mr.AddPoint(x, y, z) | 113 | actors = mr.AddPoint(x, y, z) |
105 | - Publisher.sendMessage(("Add actors " + str(m.location)), | ||
106 | - (actors, m.slice_number)) | 114 | + # Publisher.sendMessage(("Add actors " + str(m.location)), |
115 | + # (actors, m.slice_number)) | ||
107 | self.current = None | 116 | self.current = None |
108 | 117 | ||
109 | if not m.is_shown: | 118 | if not m.is_shown: |
@@ -186,8 +195,8 @@ class MeasurementManager(object): | @@ -186,8 +195,8 @@ class MeasurementManager(object): | ||
186 | x, y, z = position | 195 | x, y, z = position |
187 | actors = mr.AddPoint(x, y, z) | 196 | actors = mr.AddPoint(x, y, z) |
188 | m.points.append(position) | 197 | m.points.append(position) |
189 | - Publisher.sendMessage("Add actors " + str(location), | ||
190 | - (actors, m.slice_number)) | 198 | + # Publisher.sendMessage("Add actors " + str(location), |
199 | + # (actors, m.slice_number)) | ||
191 | 200 | ||
192 | if mr.IsComplete(): | 201 | if mr.IsComplete(): |
193 | index = prj.Project().AddMeasurement(m) | 202 | index = prj.Project().AddMeasurement(m) |
@@ -394,6 +403,7 @@ class LinearMeasure(object): | @@ -394,6 +403,7 @@ class LinearMeasure(object): | ||
394 | self.point_actor2 = None | 403 | self.point_actor2 = None |
395 | self.line_actor = None | 404 | self.line_actor = None |
396 | self.text_actor = None | 405 | self.text_actor = None |
406 | + self.renderer = None | ||
397 | if not representation: | 407 | if not representation: |
398 | representation = CirclePointRepresentation(colour) | 408 | representation = CirclePointRepresentation(colour) |
399 | self.representation = representation | 409 | self.representation = representation |
@@ -414,13 +424,31 @@ class LinearMeasure(object): | @@ -414,13 +424,31 @@ class LinearMeasure(object): | ||
414 | return (self.point_actor2, self.line_actor, self.text_actor) | 424 | return (self.point_actor2, self.line_actor, self.text_actor) |
415 | 425 | ||
416 | def SetPoint1(self, x, y, z): | 426 | def SetPoint1(self, x, y, z): |
417 | - self.points.append((x, y, z)) | ||
418 | - self.point_actor1 = self.representation.GetRepresentation(x, y, z) | 427 | + if len(self.points) == 0: |
428 | + self.points.append((x, y, z)) | ||
429 | + self.point_actor1 = self.representation.GetRepresentation(x, y, z) | ||
430 | + else: | ||
431 | + self.points[0] = (x, y, z) | ||
432 | + if len(self.points) == 2: | ||
433 | + self.Remove() | ||
434 | + self.point_actor1 = self.representation.GetRepresentation(*self.points[0]) | ||
435 | + self.point_actor2 = self.representation.GetRepresentation(*self.points[1]) | ||
436 | + self.CreateMeasure() | ||
437 | + else: | ||
438 | + self.Remove() | ||
439 | + self.point_actor1 = self.representation.GetRepresentation(*self.points[0]) | ||
419 | 440 | ||
420 | def SetPoint2(self, x, y, z): | 441 | def SetPoint2(self, x, y, z): |
421 | - self.points.append((x, y, z)) | ||
422 | - self.point_actor2 = self.representation.GetRepresentation(x, y, z) | ||
423 | - self.CreateMeasure() | 442 | + if len(self.points) == 1: |
443 | + self.points.append((x, y, z)) | ||
444 | + self.point_actor2 = self.representation.GetRepresentation(*self.points[1]) | ||
445 | + self.CreateMeasure() | ||
446 | + else: | ||
447 | + self.points[1] = (x, y, z) | ||
448 | + self.Remove() | ||
449 | + self.point_actor1 = self.representation.GetRepresentation(*self.points[0]) | ||
450 | + self.point_actor2 = self.representation.GetRepresentation(*self.points[1]) | ||
451 | + self.CreateMeasure() | ||
424 | 452 | ||
425 | def CreateMeasure(self): | 453 | def CreateMeasure(self): |
426 | self._draw_line() | 454 | self._draw_line() |
@@ -473,22 +501,22 @@ class LinearMeasure(object): | @@ -473,22 +501,22 @@ class LinearMeasure(object): | ||
473 | 501 | ||
474 | def SetRenderer(self, renderer): | 502 | def SetRenderer(self, renderer): |
475 | if self.point_actor1: | 503 | if self.point_actor1: |
476 | - self.render.RemoveActor(self.point_actor1) | 504 | + self.renderer.RemoveActor(self.point_actor1) |
477 | renderer.AddActor(self.point_actor1) | 505 | renderer.AddActor(self.point_actor1) |
478 | 506 | ||
479 | if self.point_actor2: | 507 | if self.point_actor2: |
480 | - self.render.RemoveActor(self.point_actor2) | 508 | + self.renderer.RemoveActor(self.point_actor2) |
481 | renderer.AddActor(self.point_actor2) | 509 | renderer.AddActor(self.point_actor2) |
482 | 510 | ||
483 | if self.line_actor: | 511 | if self.line_actor: |
484 | - self.render.RemoveActor(self.line_actor) | 512 | + self.renderer.RemoveActor(self.line_actor) |
485 | renderer.AddActor(self.line_actor) | 513 | renderer.AddActor(self.line_actor) |
486 | 514 | ||
487 | if self.text_actor: | 515 | if self.text_actor: |
488 | - self.render.RemoveActor(self.text_actor) | 516 | + self.renderer.RemoveActor(self.text_actor) |
489 | renderer.AddActor(self.text_actor) | 517 | renderer.AddActor(self.text_actor) |
490 | 518 | ||
491 | - self.render = renderer | 519 | + self.renderer = renderer |
492 | 520 | ||
493 | def SetVisibility(self, v): | 521 | def SetVisibility(self, v): |
494 | self.point_actor1.SetVisibility(v) | 522 | self.point_actor1.SetVisibility(v) |
@@ -513,19 +541,19 @@ class LinearMeasure(object): | @@ -513,19 +541,19 @@ class LinearMeasure(object): | ||
513 | 541 | ||
514 | def Remove(self): | 542 | def Remove(self): |
515 | if self.point_actor1: | 543 | if self.point_actor1: |
516 | - self.render.RemoveActor(self.point_actor1) | 544 | + self.renderer.RemoveActor(self.point_actor1) |
517 | del self.point_actor1 | 545 | del self.point_actor1 |
518 | 546 | ||
519 | if self.point_actor2: | 547 | if self.point_actor2: |
520 | - self.render.RemoveActor(self.point_actor2) | 548 | + self.renderer.RemoveActor(self.point_actor2) |
521 | del self.point_actor2 | 549 | del self.point_actor2 |
522 | 550 | ||
523 | if self.line_actor: | 551 | if self.line_actor: |
524 | - self.render.RemoveActor(self.line_actor) | 552 | + self.renderer.RemoveActor(self.line_actor) |
525 | del self.line_actor | 553 | del self.line_actor |
526 | 554 | ||
527 | if self.text_actor: | 555 | if self.text_actor: |
528 | - self.render.RemoveActor(self.text_actor) | 556 | + self.renderer.RemoveActor(self.text_actor) |
529 | del self.text_actor | 557 | del self.text_actor |
530 | 558 | ||
531 | # def __del__(self): | 559 | # def __del__(self): |
@@ -707,47 +735,47 @@ class AngularMeasure(object): | @@ -707,47 +735,47 @@ class AngularMeasure(object): | ||
707 | 735 | ||
708 | def Remove(self): | 736 | def Remove(self): |
709 | if self.point_actor1: | 737 | if self.point_actor1: |
710 | - self.render.RemoveActor(self.point_actor1) | 738 | + self.renderer.RemoveActor(self.point_actor1) |
711 | del self.point_actor1 | 739 | del self.point_actor1 |
712 | 740 | ||
713 | if self.point_actor2: | 741 | if self.point_actor2: |
714 | - self.render.RemoveActor(self.point_actor2) | 742 | + self.renderer.RemoveActor(self.point_actor2) |
715 | del self.point_actor2 | 743 | del self.point_actor2 |
716 | 744 | ||
717 | if self.point_actor3: | 745 | if self.point_actor3: |
718 | - self.render.RemoveActor(self.point_actor3) | 746 | + self.renderer.RemoveActor(self.point_actor3) |
719 | del self.point_actor3 | 747 | del self.point_actor3 |
720 | 748 | ||
721 | if self.line_actor: | 749 | if self.line_actor: |
722 | - self.render.RemoveActor(self.line_actor) | 750 | + self.renderer.RemoveActor(self.line_actor) |
723 | del self.line_actor | 751 | del self.line_actor |
724 | 752 | ||
725 | if self.text_actor: | 753 | if self.text_actor: |
726 | - self.render.RemoveActor(self.text_actor) | 754 | + self.renderer.RemoveActor(self.text_actor) |
727 | del self.text_actor | 755 | del self.text_actor |
728 | 756 | ||
729 | def SetRenderer(self, renderer): | 757 | def SetRenderer(self, renderer): |
730 | if self.point_actor1: | 758 | if self.point_actor1: |
731 | - self.render.RemoveActor(self.point_actor1) | 759 | + self.renderer.RemoveActor(self.point_actor1) |
732 | renderer.AddActor(self.point_actor1) | 760 | renderer.AddActor(self.point_actor1) |
733 | 761 | ||
734 | if self.point_actor2: | 762 | if self.point_actor2: |
735 | - self.render.RemoveActor(self.point_actor2) | 763 | + self.renderer.RemoveActor(self.point_actor2) |
736 | renderer.AddActor(self.point_actor2) | 764 | renderer.AddActor(self.point_actor2) |
737 | 765 | ||
738 | if self.point_actor3: | 766 | if self.point_actor3: |
739 | - self.render.RemoveActor(self.point_actor3) | 767 | + self.renderer.RemoveActor(self.point_actor3) |
740 | renderer.AddActor(self.point_actor3) | 768 | renderer.AddActor(self.point_actor3) |
741 | 769 | ||
742 | if self.line_actor: | 770 | if self.line_actor: |
743 | - self.render.RemoveActor(self.line_actor) | 771 | + self.renderer.RemoveActor(self.line_actor) |
744 | renderer.AddActor(self.line_actor) | 772 | renderer.AddActor(self.line_actor) |
745 | 773 | ||
746 | if self.text_actor: | 774 | if self.text_actor: |
747 | - self.render.RemoveActor(self.text_actor) | 775 | + self.renderer.RemoveActor(self.text_actor) |
748 | renderer.AddActor(self.text_actor) | 776 | renderer.AddActor(self.text_actor) |
749 | 777 | ||
750 | - self.render = renderer | 778 | + self.renderer = renderer |
751 | 779 | ||
752 | # def __del__(self): | 780 | # def __del__(self): |
753 | # self.Remove() | 781 | # self.Remove() |
invesalius/data/styles.py
@@ -353,6 +353,7 @@ class LinearMeasureInteractorStyle(DefaultInteractorStyle): | @@ -353,6 +353,7 @@ class LinearMeasureInteractorStyle(DefaultInteractorStyle): | ||
353 | self.slice_data = viewer.slice_data | 353 | self.slice_data = viewer.slice_data |
354 | 354 | ||
355 | self.measures = MeasureData() | 355 | self.measures = MeasureData() |
356 | + self.selected = None | ||
356 | 357 | ||
357 | spacing = self.slice_data.actor.GetInput().GetSpacing() | 358 | spacing = self.slice_data.actor.GetInput().GetSpacing() |
358 | 359 | ||
@@ -372,28 +373,82 @@ class LinearMeasureInteractorStyle(DefaultInteractorStyle): | @@ -372,28 +373,82 @@ class LinearMeasureInteractorStyle(DefaultInteractorStyle): | ||
372 | self.picker.PickFromListOn() | 373 | self.picker.PickFromListOn() |
373 | 374 | ||
374 | self.AddObserver("LeftButtonPressEvent", self.OnInsertLinearMeasurePoint) | 375 | self.AddObserver("LeftButtonPressEvent", self.OnInsertLinearMeasurePoint) |
376 | + self.AddObserver("LeftButtonReleaseEvent", self.OnReleaseMeasurePoint) | ||
377 | + self.AddObserver("MouseMoveEvent", self.OnMoveMeasurePoint) | ||
375 | 378 | ||
376 | def OnInsertLinearMeasurePoint(self, obj, evt): | 379 | def OnInsertLinearMeasurePoint(self, obj, evt): |
377 | - iren = obj.GetInteractor() | ||
378 | - mx,my = iren.GetEventPosition() | ||
379 | - render = iren.FindPokedRenderer(mx, my) | ||
380 | slice_number = self.slice_data.number | 380 | slice_number = self.slice_data.number |
381 | - self.picker.AddPickList(self.slice_data.actor) | ||
382 | - self.picker.Pick(mx, my, 0, render) | ||
383 | - x, y, z = self.picker.GetPickPosition() | ||
384 | - self.picker.DeletePickList(self.slice_data.actor) | 381 | + x, y, z = self._get_pos_clicked() |
382 | + | ||
383 | + selected = self._verify_clicked(x, y, z) | ||
384 | + if selected: | ||
385 | + self.selected = selected | ||
386 | + else: | ||
387 | + if self.picker.GetViewProp(): | ||
388 | + Publisher.sendMessage("Add measurement point", | ||
389 | + ((x, y,z), const.LINEAR, | ||
390 | + ORIENTATIONS[self.orientation], | ||
391 | + slice_number, self.radius)) | ||
392 | + self.viewer.interactor.Render() | ||
393 | + | ||
394 | + def OnReleaseMeasurePoint(self, obj, evt): | ||
395 | + if self.selected: | ||
396 | + print "Changing Position" | ||
397 | + n, m, mr = self.selected | ||
398 | + x, y, z = self._get_pos_clicked() | ||
399 | + ren = self.slice_data.renderer | ||
400 | + mr.renderer = ren | ||
401 | + if n == 0: | ||
402 | + mr.SetPoint1(x, y, z) | ||
403 | + m.points[0] = x, y, z | ||
404 | + elif n == 1: | ||
405 | + mr.SetPoint2(x, y, z) | ||
406 | + m.points[1] = x, y, z | ||
385 | 407 | ||
386 | - if self.picker.GetViewProp(): | ||
387 | - Publisher.sendMessage("Add measurement point", | ||
388 | - ((x, y,z), const.LINEAR, | ||
389 | - ORIENTATIONS[self.orientation], | ||
390 | - slice_number, self.radius)) | ||
391 | self.viewer.interactor.Render() | 408 | self.viewer.interactor.Render() |
409 | + Publisher.sendMessage('Reload actual slice %s' % self.orientation) | ||
410 | + self.selected = None | ||
411 | + | ||
412 | + def OnMoveMeasurePoint(self, obj, evt): | ||
413 | + if self.selected: | ||
414 | + print "Changing Position" | ||
415 | + n, m, mr = self.selected | ||
416 | + x, y, z = self._get_pos_clicked() | ||
417 | + ren = self.slice_data.renderer | ||
418 | + mr.renderer = ren | ||
419 | + if n == 0: | ||
420 | + mr.SetPoint1(x, y, z) | ||
421 | + m.points[0] = x, y, z | ||
422 | + elif n == 1: | ||
423 | + mr.SetPoint2(x, y, z) | ||
424 | + m.points[1] = x, y, z | ||
392 | 425 | ||
426 | + self.viewer.interactor.Render() | ||
427 | + Publisher.sendMessage('Reload actual slice %s' % self.orientation) | ||
393 | 428 | ||
394 | def CleanUp(self): | 429 | def CleanUp(self): |
395 | Publisher.sendMessage("Remove incomplete measurements") | 430 | Publisher.sendMessage("Remove incomplete measurements") |
396 | 431 | ||
432 | + def _get_pos_clicked(self): | ||
433 | + iren = self.viewer.interactor | ||
434 | + mx,my = iren.GetEventPosition() | ||
435 | + render = iren.FindPokedRenderer(mx, my) | ||
436 | + self.picker.AddPickList(self.slice_data.actor) | ||
437 | + self.picker.Pick(mx, my, 0, render) | ||
438 | + x, y, z = self.picker.GetPickPosition() | ||
439 | + self.picker.DeletePickList(self.slice_data.actor) | ||
440 | + return (x, y, z) | ||
441 | + | ||
442 | + def _verify_clicked(self, x, y, z): | ||
443 | + slice_number = self.slice_data.number | ||
444 | + if slice_number in self.measures.measures[self._ori]: | ||
445 | + for m, mr in self.measures.measures[self._ori][slice_number]: | ||
446 | + for n, p in enumerate(m.points): | ||
447 | + px, py, pz = p | ||
448 | + dist = ((px-x)**2 + (py-y)**2 + (pz-z)**2)**0.5 | ||
449 | + if dist < 2: | ||
450 | + return (n, m, mr) | ||
451 | + return None | ||
397 | 452 | ||
398 | class AngularMeasureInteractorStyle(DefaultInteractorStyle): | 453 | class AngularMeasureInteractorStyle(DefaultInteractorStyle): |
399 | """ | 454 | """ |
invesalius/data/viewer_slice.py
@@ -171,7 +171,7 @@ class Viewer(wx.Panel): | @@ -171,7 +171,7 @@ class Viewer(wx.Panel): | ||
171 | self.layout = (1, 1) | 171 | self.layout = (1, 1) |
172 | self.orientation_texts = [] | 172 | self.orientation_texts = [] |
173 | 173 | ||
174 | - self.measures = [] | 174 | + self.measures = measures.MeasureData() |
175 | self.actors_by_slice_number = {} | 175 | self.actors_by_slice_number = {} |
176 | self.renderers_by_slice_number = {} | 176 | self.renderers_by_slice_number = {} |
177 | 177 | ||
@@ -1183,6 +1183,14 @@ class Viewer(wx.Panel): | @@ -1183,6 +1183,14 @@ class Viewer(wx.Panel): | ||
1183 | for actor in self.actors_by_slice_number.get(index, []): | 1183 | for actor in self.actors_by_slice_number.get(index, []): |
1184 | self.slice_data.renderer.AddActor(actor) | 1184 | self.slice_data.renderer.AddActor(actor) |
1185 | 1185 | ||
1186 | + for (m, mr) in self.measures[self.orientation].get(self.slice_data.number, []): | ||
1187 | + for actor in mr.GetActors(): | ||
1188 | + self.slice_data.renderer.RemoveActor(actor) | ||
1189 | + | ||
1190 | + for (m, mr) in self.measures[self.orientation].get(index, []): | ||
1191 | + for actor in mr.GetActors(): | ||
1192 | + self.slice_data.renderer.AddActor(actor) | ||
1193 | + | ||
1186 | if self.slice_._type_projection == const.PROJECTION_NORMAL: | 1194 | if self.slice_._type_projection == const.PROJECTION_NORMAL: |
1187 | self.slice_data.SetNumber(index) | 1195 | self.slice_data.SetNumber(index) |
1188 | else: | 1196 | else: |