Commit a3979279e26d5cb05a239c8f07c051bcde287c02
1 parent
2b11a51c
Exists in
master
and in
68 other branches
FIX: Fixed the circle cursor proportion
Showing
2 changed files
with
56 additions
and
12 deletions
Show diff stats
invesalius/data/cursor_actors.py
... | ... | @@ -2,6 +2,28 @@ from math import * |
2 | 2 | |
3 | 3 | import vtk |
4 | 4 | |
5 | +def frange(start, end=None, inc=None): | |
6 | + "A range function, that does accept float increments..." | |
7 | + | |
8 | + if end == None: | |
9 | + end = start + 0.0 | |
10 | + start = 0.0 | |
11 | + | |
12 | + if inc == None: | |
13 | + inc = 1.0 | |
14 | + | |
15 | + L = [] | |
16 | + while 1: | |
17 | + next = start + len(L) * inc | |
18 | + if inc > 0 and next >= end: | |
19 | + break | |
20 | + elif inc < 0 and next <= end: | |
21 | + break | |
22 | + L.append(next) | |
23 | + | |
24 | + return L | |
25 | + | |
26 | + | |
5 | 27 | class CursorCircle: |
6 | 28 | # TODO: Think and try to change this class to an actor |
7 | 29 | # CursorCircleActor(vtk.vtkActor) |
... | ... | @@ -14,6 +36,7 @@ class CursorCircle: |
14 | 36 | self.position = (0 ,0, 1) |
15 | 37 | self.points = [] |
16 | 38 | self.orientation = "AXIAL" |
39 | + self.spacing = (1, 1, 1) | |
17 | 40 | |
18 | 41 | self.mapper = vtk.vtkPolyDataMapper() |
19 | 42 | self.disk = vtk.vtkDiskSource() |
... | ... | @@ -54,19 +77,24 @@ class CursorCircle: |
54 | 77 | xc = 0 |
55 | 78 | yc = 0 |
56 | 79 | z = 0 |
80 | + xs, ys, zs = self.spacing | |
81 | + orientation_based_spacing = {"AXIAL" : (xs, ys), | |
82 | + "SAGITAL" : (ys, zs), | |
83 | + "CORONAL" : (xs, zs) } | |
84 | + xs, ys = orientation_based_spacing[self.orientation] | |
57 | 85 | self.pixel_list = [] |
58 | - radius = int(self.radius) | |
59 | - for i in xrange(int(yc - radius), int(yc + radius)): | |
86 | + radius = self.radius | |
87 | + for i in frange(yc - radius, yc + radius, ys): | |
60 | 88 | # distance from the line to the circle's center |
61 | 89 | d = yc - i |
62 | 90 | # line size |
63 | - line = sqrt(round(radius ** 2) - round(d ** 2)) * 2 | |
91 | + line = sqrt(radius**2 - d**2) * 2 | |
64 | 92 | # line initial x |
65 | - xi = int(xc - line/2) | |
93 | + xi = xc - line/2 | |
66 | 94 | # line final |
67 | - xf = int(line/2 + xc) | |
95 | + xf = line/2 + xc | |
68 | 96 | yi = i |
69 | - for k in xrange(xi,xf): | |
97 | + for k in frange(xi,xf,xs): | |
70 | 98 | self.pixel_list.append((k, yi)) |
71 | 99 | |
72 | 100 | def SetSize(self, radius): |
... | ... | @@ -97,15 +125,22 @@ class CursorCircle: |
97 | 125 | self.position = position |
98 | 126 | self.actor.SetPosition(position) |
99 | 127 | |
128 | + def SetEditionPosition(self, position): | |
129 | + self.edition_position = position | |
130 | + | |
131 | + def SetSpacing(self, spacing): | |
132 | + self.spacing = spacing | |
133 | + | |
100 | 134 | def GetPixels(self): |
101 | - px, py, pz = self.position | |
135 | + px, py, pz = self.edition_position | |
102 | 136 | orient = self.orientation |
137 | + xs, ys, zs = self.spacing | |
103 | 138 | for pixel_0,pixel_1 in self.pixel_list: |
104 | 139 | # The position of the pixels in this list is relative (based only on |
105 | 140 | # the area, and not the cursor position). |
106 | 141 | # Let's calculate the absolute position |
107 | 142 | # TODO: Optimize this!!!! |
108 | - absolute_pixel = {"AXIAL": (px + pixel_0, py + pixel_1, pz), | |
109 | - "CORONAL": (px + pixel_0, py, pz + pixel_1), | |
110 | - "SAGITAL": (px, py + pixel_0, pz + pixel_1)} | |
143 | + absolute_pixel = {"AXIAL": (px + pixel_0 / xs , py + pixel_1 / ys, pz), | |
144 | + "CORONAL": (px + pixel_0 / xs, py, pz + pixel_1 / zs), | |
145 | + "SAGITAL": (px, py + pixel_0 / ys, pz + pixel_1 / zs) } | |
111 | 146 | yield absolute_pixel[orient] | ... | ... |
invesalius/data/viewer_slice.py
... | ... | @@ -145,6 +145,7 @@ class Viewer(wx.Panel): |
145 | 145 | def OnBrushMove(self, obj, evt_vtk): |
146 | 146 | coord = self.GetCoordinateCursor() |
147 | 147 | self.cursor.SetPosition(coord) |
148 | + self.cursor.SetEditionPosition(self.GetCoordinateCursorEdition()) | |
148 | 149 | self.ren.Render() |
149 | 150 | if self.mouse_pressed: |
150 | 151 | print "Edit pixel region based on origin:", coord |
... | ... | @@ -208,13 +209,20 @@ class Viewer(wx.Panel): |
208 | 209 | |
209 | 210 | return coord |
210 | 211 | |
211 | - | |
212 | 212 | def GetCoordinateCursor(self): |
213 | 213 | |
214 | 214 | # Find position |
215 | 215 | mouse_x, mouse_y = self.interactor.GetEventPosition() |
216 | 216 | self.pick.Pick(mouse_x, mouse_y, 0, self.ren) |
217 | 217 | x, y, z = self.pick.GetPickPosition() |
218 | + return x, y, z | |
219 | + | |
220 | + def GetCoordinateCursorEdition(self): | |
221 | + | |
222 | + # Find position | |
223 | + mouse_x, mouse_y = self.interactor.GetEventPosition() | |
224 | + self.pick.Pick(mouse_x, mouse_y, 0, self.ren) | |
225 | + x, y, z = self.pick.GetPickPosition() | |
218 | 226 | |
219 | 227 | # First we fix the position origin, based on vtkActor bounds |
220 | 228 | bounds = self.actor.GetBounds() |
... | ... | @@ -241,7 +249,7 @@ class Viewer(wx.Panel): |
241 | 249 | z = (z * dimensions[2]) / dz |
242 | 250 | except ZeroDivisionError: |
243 | 251 | z = self.slice_number |
244 | - | |
252 | + | |
245 | 253 | return x,y,z |
246 | 254 | |
247 | 255 | def __bind_events(self): |
... | ... | @@ -296,6 +304,7 @@ class Viewer(wx.Panel): |
296 | 304 | self.scroll.SetScrollbar(wx.SB_VERTICAL, 1, max_slice_number, |
297 | 305 | max_slice_number) |
298 | 306 | self.SetScrollPosition(0) |
307 | + self.cursor.SetSpacing(imagedata.GetSpacing()) | |
299 | 308 | |
300 | 309 | def SetOrientation(self, orientation): |
301 | 310 | self.orientation = orientation | ... | ... |