Commit 46b264138daba63e24595f9d6d6ab435eae854cb
1 parent
ed793cd1
Exists in
master
and in
68 other branches
ENH: Changing in the window width & leve afecting the clut raycasting widget. Ad…
…ded a function to sort points in the clut raycasting widget and added commentaries in the source code
Showing
2 changed files
with
46 additions
and
6 deletions
Show diff stats
invesalius/data/volume.py
@@ -369,8 +369,8 @@ class Volume(): | @@ -369,8 +369,8 @@ class Volume(): | ||
369 | convolve.SetKernel5x5([i/60.0 for i in Kernels[filter]]) | 369 | convolve.SetKernel5x5([i/60.0 for i in Kernels[filter]]) |
370 | convolve.AddObserver("ProgressEvent", lambda obj,evt: | 370 | convolve.AddObserver("ProgressEvent", lambda obj,evt: |
371 | update_progress(convolve, "%s ..." % filter)) | 371 | update_progress(convolve, "%s ..." % filter)) |
372 | - convolve.Update() | ||
373 | imagedata = convolve.GetOutput() | 372 | imagedata = convolve.GetOutput() |
373 | + convolve.GetOutput().ReleaseDataFlagOn() | ||
374 | return imagedata | 374 | return imagedata |
375 | 375 | ||
376 | def LoadVolume(self): | 376 | def LoadVolume(self): |
@@ -408,7 +408,6 @@ class Volume(): | @@ -408,7 +408,6 @@ class Volume(): | ||
408 | else: | 408 | else: |
409 | self.Create8bColorTable(scale) | 409 | self.Create8bColorTable(scale) |
410 | self.Create8bOpacityTable(scale) | 410 | self.Create8bOpacityTable(scale) |
411 | - | ||
412 | image2 = self.ApplyConvolution(image2.GetOutput()) | 411 | image2 = self.ApplyConvolution(image2.GetOutput()) |
413 | self.final_imagedata = image2 | 412 | self.final_imagedata = image2 |
414 | 413 |
invesalius/gui/widgets/clut_raycasting.py
@@ -46,9 +46,13 @@ class CLUTRaycastingWidget(wx.Panel): | @@ -46,9 +46,13 @@ class CLUTRaycastingWidget(wx.Panel): | ||
46 | self.dragged = False | 46 | self.dragged = False |
47 | self.point_dragged = None | 47 | self.point_dragged = None |
48 | self.__bind_events_wx() | 48 | self.__bind_events_wx() |
49 | + self.__bind_events() | ||
49 | self.Show() | 50 | self.Show() |
50 | 51 | ||
51 | def SetRange(self, range): | 52 | def SetRange(self, range): |
53 | + """ | ||
54 | + Se the range from hounsfield | ||
55 | + """ | ||
52 | self.init, self.end = range | 56 | self.init, self.end = range |
53 | print "Range", range | 57 | print "Range", range |
54 | self.CreatePixelArray() | 58 | self.CreatePixelArray() |
@@ -67,14 +71,18 @@ class CLUTRaycastingWidget(wx.Panel): | @@ -67,14 +71,18 @@ class CLUTRaycastingWidget(wx.Panel): | ||
67 | self.Bind(wx.EVT_SIZE, self.OnSize) | 71 | self.Bind(wx.EVT_SIZE, self.OnSize) |
68 | self.Bind(wx.EVT_MOUSEWHEEL, self.OnWheel) | 72 | self.Bind(wx.EVT_MOUSEWHEEL, self.OnWheel) |
69 | 73 | ||
74 | + def __bind_events(self): | ||
70 | ps.Publisher().subscribe(self.SetRaycastPreset, | 75 | ps.Publisher().subscribe(self.SetRaycastPreset, |
71 | 'Set raycasting preset') | 76 | 'Set raycasting preset') |
77 | + ps.Publisher().subscribe( self.RefreshPoints, | ||
78 | + 'Refresh raycasting widget points') | ||
72 | 79 | ||
73 | def OnEraseBackground(self, evt): | 80 | def OnEraseBackground(self, evt): |
74 | pass | 81 | pass |
75 | 82 | ||
76 | def OnClick(self, evt): | 83 | def OnClick(self, evt): |
77 | point = self._has_clicked_in_a_point(evt.GetPositionTuple()) | 84 | point = self._has_clicked_in_a_point(evt.GetPositionTuple()) |
85 | + # A point has been selected. It can be dragged. | ||
78 | if point: | 86 | if point: |
79 | self.dragged = True | 87 | self.dragged = True |
80 | self.point_dragged = point | 88 | self.point_dragged = point |
@@ -82,6 +90,7 @@ class CLUTRaycastingWidget(wx.Panel): | @@ -82,6 +90,7 @@ class CLUTRaycastingWidget(wx.Panel): | ||
82 | return | 90 | return |
83 | else: | 91 | else: |
84 | p = self._has_clicked_in_line(evt.GetPositionTuple()) | 92 | p = self._has_clicked_in_line(evt.GetPositionTuple()) |
93 | + # The user clicked in the line. Insert a new point. | ||
85 | if p: | 94 | if p: |
86 | n, p = p | 95 | n, p = p |
87 | self.points[n].insert(p, {'x': 0, 'y': 0}) | 96 | self.points[n].insert(p, {'x': 0, 'y': 0}) |
@@ -129,6 +138,10 @@ class CLUTRaycastingWidget(wx.Panel): | @@ -129,6 +138,10 @@ class CLUTRaycastingWidget(wx.Panel): | ||
129 | evt.Skip() | 138 | evt.Skip() |
130 | 139 | ||
131 | def OnRelease(self, evt): | 140 | def OnRelease(self, evt): |
141 | + """ | ||
142 | + Generate a EVT_CLUT_POINT_CHANGED event indicating that a change has | ||
143 | + been occurred in the preset points. | ||
144 | + """ | ||
132 | if self.to_render: | 145 | if self.to_render: |
133 | evt = CLUTEvent(myEVT_CLUT_POINT_CHANGED, self.GetId()) | 146 | evt = CLUTEvent(myEVT_CLUT_POINT_CHANGED, self.GetId()) |
134 | self.GetEventHandler().ProcessEvent(evt) | 147 | self.GetEventHandler().ProcessEvent(evt) |
@@ -136,6 +149,10 @@ class CLUTRaycastingWidget(wx.Panel): | @@ -136,6 +149,10 @@ class CLUTRaycastingWidget(wx.Panel): | ||
136 | self.to_render = False | 149 | self.to_render = False |
137 | 150 | ||
138 | def OnWheel(self, evt): | 151 | def OnWheel(self, evt): |
152 | + """ | ||
153 | + Increase or decrease the range from hounsfield scale showed. It | ||
154 | + doesn't change values in preset, only to visualization. | ||
155 | + """ | ||
139 | direction = evt.GetWheelRotation() / evt.GetWheelDelta() | 156 | direction = evt.GetWheelRotation() / evt.GetWheelDelta() |
140 | init = self.init - 10 * direction | 157 | init = self.init - 10 * direction |
141 | end = self.end + 10 * direction | 158 | end = self.end + 10 * direction |
@@ -144,6 +161,7 @@ class CLUTRaycastingWidget(wx.Panel): | @@ -144,6 +161,7 @@ class CLUTRaycastingWidget(wx.Panel): | ||
144 | self.Refresh() | 161 | self.Refresh() |
145 | 162 | ||
146 | def OnMotion(self, evt): | 163 | def OnMotion(self, evt): |
164 | + # User dragging a point | ||
147 | if self.dragged: | 165 | if self.dragged: |
148 | self.to_render = True | 166 | self.to_render = True |
149 | i,j = self.point_dragged | 167 | i,j = self.point_dragged |
@@ -154,7 +172,7 @@ class CLUTRaycastingWidget(wx.Panel): | @@ -154,7 +172,7 @@ class CLUTRaycastingWidget(wx.Panel): | ||
154 | 172 | ||
155 | if y >= height - self.padding: | 173 | if y >= height - self.padding: |
156 | y = height - self.padding | 174 | y = height - self.padding |
157 | - | 175 | + |
158 | if y <= self.padding: | 176 | if y <= self.padding: |
159 | y = self.padding | 177 | y = self.padding |
160 | 178 | ||
@@ -226,6 +244,10 @@ class CLUTRaycastingWidget(wx.Panel): | @@ -226,6 +244,10 @@ class CLUTRaycastingWidget(wx.Panel): | ||
226 | return None | 244 | return None |
227 | 245 | ||
228 | def _has_clicked_in_line(self, position): | 246 | def _has_clicked_in_line(self, position): |
247 | + """ | ||
248 | + Verify if was clicked in a line. If yes, it returns the insertion | ||
249 | + position in the point list. | ||
250 | + """ | ||
229 | for n, point in enumerate(self.pixels_points): | 251 | for n, point in enumerate(self.pixels_points): |
230 | p = bisect.bisect([i[0] for i in point], position[0]) | 252 | p = bisect.bisect([i[0] for i in point], position[0]) |
231 | print p | 253 | print p |
@@ -404,11 +426,28 @@ class CLUTRaycastingWidget(wx.Panel): | @@ -404,11 +426,28 @@ class CLUTRaycastingWidget(wx.Panel): | ||
404 | self.histogram_pixel_points.append((x, y)) | 426 | self.histogram_pixel_points.append((x, y)) |
405 | 427 | ||
406 | def CreatePixelArray(self): | 428 | def CreatePixelArray(self): |
429 | + """ | ||
430 | + Create a list with points (in pixel x, y coordinate) to draw based in | ||
431 | + the preset points (Hounsfield scale, opacity). | ||
432 | + """ | ||
407 | self.pixels_points = [] | 433 | self.pixels_points = [] |
434 | + self.__sort_pixel_points() | ||
408 | for curve in self.points: | 435 | for curve in self.points: |
409 | self.pixels_points.append([self.HounsfieldToPixel(i) for i in curve]) | 436 | self.pixels_points.append([self.HounsfieldToPixel(i) for i in curve]) |
410 | self._build_histogram() | 437 | self._build_histogram() |
411 | 438 | ||
439 | + def __sort_pixel_points(self): | ||
440 | + """ | ||
441 | + Sort the pixel points (colours and points) maintaining the reference | ||
442 | + between colours and points. It's necessary mainly in negative window | ||
443 | + width when the user interacts with this widgets. | ||
444 | + """ | ||
445 | + for n, (point, colour) in enumerate(zip(self.points, self.colours)): | ||
446 | + point_colour = zip(point, colour) | ||
447 | + point_colour.sort(key=lambda x: x[0]['x']) | ||
448 | + self.points[n] = [i[0] for i in point_colour] | ||
449 | + self.colours[n] = [i[1] for i in point_colour] | ||
450 | + | ||
412 | def HounsfieldToPixel(self, h_pt): | 451 | def HounsfieldToPixel(self, h_pt): |
413 | """ | 452 | """ |
414 | Given a Hounsfield point(graylevel, opacity), returns a pixel point in the canvas. | 453 | Given a Hounsfield point(graylevel, opacity), returns a pixel point in the canvas. |
@@ -419,7 +458,6 @@ class CLUTRaycastingWidget(wx.Panel): | @@ -419,7 +458,6 @@ class CLUTRaycastingWidget(wx.Panel): | ||
419 | proportion = width * 1.0 / (self.end - self.init) | 458 | proportion = width * 1.0 / (self.end - self.init) |
420 | x = (h_pt['x'] - self.init) * proportion | 459 | x = (h_pt['x'] - self.init) * proportion |
421 | y = height - (h_pt['y'] * height) + self.padding | 460 | y = height - (h_pt['y'] * height) + self.padding |
422 | - print y | ||
423 | return [x,y] | 461 | return [x,y] |
424 | 462 | ||
425 | def PixelToHounsfield(self, i, j): | 463 | def PixelToHounsfield(self, i, j): |
@@ -434,8 +472,6 @@ class CLUTRaycastingWidget(wx.Panel): | @@ -434,8 +472,6 @@ class CLUTRaycastingWidget(wx.Panel): | ||
434 | y = (height - self.pixels_points[i][j][1] + self.padding) * 1.0 / height | 472 | y = (height - self.pixels_points[i][j][1] + self.padding) * 1.0 / height |
435 | self.points[i][j]['x'] = x | 473 | self.points[i][j]['x'] = x |
436 | self.points[i][j]['y'] = y | 474 | self.points[i][j]['y'] = y |
437 | - self.colours[i][j] | ||
438 | - print x,y | ||
439 | 475 | ||
440 | def SetRaycastPreset(self, preset): | 476 | def SetRaycastPreset(self, preset): |
441 | preset = project.Project().raycasting_preset | 477 | preset = project.Project().raycasting_preset |
@@ -449,6 +485,11 @@ class CLUTRaycastingWidget(wx.Panel): | @@ -449,6 +485,11 @@ class CLUTRaycastingWidget(wx.Panel): | ||
449 | self.CreatePixelArray() | 485 | self.CreatePixelArray() |
450 | else: | 486 | else: |
451 | self.to_draw_points = 0 | 487 | self.to_draw_points = 0 |
488 | + self.Refresh() | ||
489 | + | ||
490 | + def RefreshPoints(self, pubsub_evt): | ||
491 | + self.CreatePixelArray() | ||
492 | + self.Refresh() | ||
452 | 493 | ||
453 | def SetHistrogramArray(self, h_array): | 494 | def SetHistrogramArray(self, h_array): |
454 | self.histogram_array = h_array | 495 | self.histogram_array = h_array |