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 | 369 | convolve.SetKernel5x5([i/60.0 for i in Kernels[filter]]) |
| 370 | 370 | convolve.AddObserver("ProgressEvent", lambda obj,evt: |
| 371 | 371 | update_progress(convolve, "%s ..." % filter)) |
| 372 | - convolve.Update() | |
| 373 | 372 | imagedata = convolve.GetOutput() |
| 373 | + convolve.GetOutput().ReleaseDataFlagOn() | |
| 374 | 374 | return imagedata |
| 375 | 375 | |
| 376 | 376 | def LoadVolume(self): |
| ... | ... | @@ -408,7 +408,6 @@ class Volume(): |
| 408 | 408 | else: |
| 409 | 409 | self.Create8bColorTable(scale) |
| 410 | 410 | self.Create8bOpacityTable(scale) |
| 411 | - | |
| 412 | 411 | image2 = self.ApplyConvolution(image2.GetOutput()) |
| 413 | 412 | self.final_imagedata = image2 |
| 414 | 413 | ... | ... |
invesalius/gui/widgets/clut_raycasting.py
| ... | ... | @@ -46,9 +46,13 @@ class CLUTRaycastingWidget(wx.Panel): |
| 46 | 46 | self.dragged = False |
| 47 | 47 | self.point_dragged = None |
| 48 | 48 | self.__bind_events_wx() |
| 49 | + self.__bind_events() | |
| 49 | 50 | self.Show() |
| 50 | 51 | |
| 51 | 52 | def SetRange(self, range): |
| 53 | + """ | |
| 54 | + Se the range from hounsfield | |
| 55 | + """ | |
| 52 | 56 | self.init, self.end = range |
| 53 | 57 | print "Range", range |
| 54 | 58 | self.CreatePixelArray() |
| ... | ... | @@ -67,14 +71,18 @@ class CLUTRaycastingWidget(wx.Panel): |
| 67 | 71 | self.Bind(wx.EVT_SIZE, self.OnSize) |
| 68 | 72 | self.Bind(wx.EVT_MOUSEWHEEL, self.OnWheel) |
| 69 | 73 | |
| 74 | + def __bind_events(self): | |
| 70 | 75 | ps.Publisher().subscribe(self.SetRaycastPreset, |
| 71 | 76 | 'Set raycasting preset') |
| 77 | + ps.Publisher().subscribe( self.RefreshPoints, | |
| 78 | + 'Refresh raycasting widget points') | |
| 72 | 79 | |
| 73 | 80 | def OnEraseBackground(self, evt): |
| 74 | 81 | pass |
| 75 | 82 | |
| 76 | 83 | def OnClick(self, evt): |
| 77 | 84 | point = self._has_clicked_in_a_point(evt.GetPositionTuple()) |
| 85 | + # A point has been selected. It can be dragged. | |
| 78 | 86 | if point: |
| 79 | 87 | self.dragged = True |
| 80 | 88 | self.point_dragged = point |
| ... | ... | @@ -82,6 +90,7 @@ class CLUTRaycastingWidget(wx.Panel): |
| 82 | 90 | return |
| 83 | 91 | else: |
| 84 | 92 | p = self._has_clicked_in_line(evt.GetPositionTuple()) |
| 93 | + # The user clicked in the line. Insert a new point. | |
| 85 | 94 | if p: |
| 86 | 95 | n, p = p |
| 87 | 96 | self.points[n].insert(p, {'x': 0, 'y': 0}) |
| ... | ... | @@ -129,6 +138,10 @@ class CLUTRaycastingWidget(wx.Panel): |
| 129 | 138 | evt.Skip() |
| 130 | 139 | |
| 131 | 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 | 145 | if self.to_render: |
| 133 | 146 | evt = CLUTEvent(myEVT_CLUT_POINT_CHANGED, self.GetId()) |
| 134 | 147 | self.GetEventHandler().ProcessEvent(evt) |
| ... | ... | @@ -136,6 +149,10 @@ class CLUTRaycastingWidget(wx.Panel): |
| 136 | 149 | self.to_render = False |
| 137 | 150 | |
| 138 | 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 | 156 | direction = evt.GetWheelRotation() / evt.GetWheelDelta() |
| 140 | 157 | init = self.init - 10 * direction |
| 141 | 158 | end = self.end + 10 * direction |
| ... | ... | @@ -144,6 +161,7 @@ class CLUTRaycastingWidget(wx.Panel): |
| 144 | 161 | self.Refresh() |
| 145 | 162 | |
| 146 | 163 | def OnMotion(self, evt): |
| 164 | + # User dragging a point | |
| 147 | 165 | if self.dragged: |
| 148 | 166 | self.to_render = True |
| 149 | 167 | i,j = self.point_dragged |
| ... | ... | @@ -154,7 +172,7 @@ class CLUTRaycastingWidget(wx.Panel): |
| 154 | 172 | |
| 155 | 173 | if y >= height - self.padding: |
| 156 | 174 | y = height - self.padding |
| 157 | - | |
| 175 | + | |
| 158 | 176 | if y <= self.padding: |
| 159 | 177 | y = self.padding |
| 160 | 178 | |
| ... | ... | @@ -226,6 +244,10 @@ class CLUTRaycastingWidget(wx.Panel): |
| 226 | 244 | return None |
| 227 | 245 | |
| 228 | 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 | 251 | for n, point in enumerate(self.pixels_points): |
| 230 | 252 | p = bisect.bisect([i[0] for i in point], position[0]) |
| 231 | 253 | print p |
| ... | ... | @@ -404,11 +426,28 @@ class CLUTRaycastingWidget(wx.Panel): |
| 404 | 426 | self.histogram_pixel_points.append((x, y)) |
| 405 | 427 | |
| 406 | 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 | 433 | self.pixels_points = [] |
| 434 | + self.__sort_pixel_points() | |
| 408 | 435 | for curve in self.points: |
| 409 | 436 | self.pixels_points.append([self.HounsfieldToPixel(i) for i in curve]) |
| 410 | 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 | 451 | def HounsfieldToPixel(self, h_pt): |
| 413 | 452 | """ |
| 414 | 453 | Given a Hounsfield point(graylevel, opacity), returns a pixel point in the canvas. |
| ... | ... | @@ -419,7 +458,6 @@ class CLUTRaycastingWidget(wx.Panel): |
| 419 | 458 | proportion = width * 1.0 / (self.end - self.init) |
| 420 | 459 | x = (h_pt['x'] - self.init) * proportion |
| 421 | 460 | y = height - (h_pt['y'] * height) + self.padding |
| 422 | - print y | |
| 423 | 461 | return [x,y] |
| 424 | 462 | |
| 425 | 463 | def PixelToHounsfield(self, i, j): |
| ... | ... | @@ -434,8 +472,6 @@ class CLUTRaycastingWidget(wx.Panel): |
| 434 | 472 | y = (height - self.pixels_points[i][j][1] + self.padding) * 1.0 / height |
| 435 | 473 | self.points[i][j]['x'] = x |
| 436 | 474 | self.points[i][j]['y'] = y |
| 437 | - self.colours[i][j] | |
| 438 | - print x,y | |
| 439 | 475 | |
| 440 | 476 | def SetRaycastPreset(self, preset): |
| 441 | 477 | preset = project.Project().raycasting_preset |
| ... | ... | @@ -449,6 +485,11 @@ class CLUTRaycastingWidget(wx.Panel): |
| 449 | 485 | self.CreatePixelArray() |
| 450 | 486 | else: |
| 451 | 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 | 494 | def SetHistrogramArray(self, h_array): |
| 454 | 495 | self.histogram_array = h_array | ... | ... |