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 |