Commit 1ea696b9fda53711b471a12973e666ae1e2e89d1

Authored by tfmoraes
1 parent ceaf535c

Using weakref reduce memory consumption in volume rendering

invesalius/control.py
... ... @@ -599,7 +599,6 @@ class Controller():
599 599 else:
600 600 prj.Project().raycasting_preset = 0
601 601 Publisher.sendMessage('Update raycasting preset')
602   - Publisher.sendMessage("Hide raycasting volume")
603 602  
604 603 def SaveRaycastingPreset(self, pubsub_evt):
605 604 preset_name = pubsub_evt.data
... ...
invesalius/data/viewer_volume.py
... ... @@ -110,11 +110,14 @@ class Viewer(wx.Panel):
110 110 self.repositioned_coronal_plan = 0
111 111 self.added_actor = 0
112 112  
  113 + self._to_show_ball = 0
  114 +
113 115 def __bind_events(self):
114 116 Publisher.subscribe(self.LoadActor,
115 117 'Load surface actor into viewer')
116 118 Publisher.subscribe(self.RemoveActor,
117 119 'Remove surface actor from viewer')
  120 + Publisher.subscribe(self.OnShowSurface, 'Show surface')
118 121 Publisher.subscribe(self.UpdateRender,
119 122 'Render volume viewer')
120 123 Publisher.subscribe(self.ChangeBackgroundColour,
... ... @@ -225,22 +228,35 @@ class Viewer(wx.Panel):
225 228 self.ball_actor.SetProperty(p)
226 229  
227 230 def ActivateBallReference(self, pubsub_evt):
228   - if not self.ball_reference:
229   - self.CreateBallReference()
230   - self.ren.AddActor(self.ball_actor)
  231 + if self._to_show_ball:
  232 + if not self.ball_reference:
  233 + self.CreateBallReference()
  234 + self.ren.AddActor(self.ball_actor)
231 235  
232 236 def DeactivateBallReference(self, pubsub_evt):
233 237 if self.ball_reference:
234 238 self.ren.RemoveActor(self.ball_actor)
235 239  
  240 + def OnShowSurface(self, pubsub_evt):
  241 + index, value = pubsub_evt.data
  242 + if value:
  243 + self._to_show_ball += 1
  244 + else:
  245 + self._to_show_ball -= 1
  246 + print "to show ball", self._to_show_ball
  247 +
236 248 def SetBallReferencePosition(self, pubsub_evt):
237 249 x, y, z = pubsub_evt.data
238 250 self.ball_reference.SetCenter(x, y, z)
239 251  
240 252 def SetBallReferencePositionBasedOnBound(self, pubsub_evt):
241   - coord = pubsub_evt.data
242   - x, y, z = bases.FlipX(coord)
243   - self.ball_reference.SetCenter(x, y, z)
  253 + if self._to_show_ball:
  254 + self.ActivateBallReference(None)
  255 + coord = pubsub_evt.data
  256 + x, y, z = bases.FlipX(coord)
  257 + self.ball_reference.SetCenter(x, y, z)
  258 + else:
  259 + self.DeactivateBallReference(None)
244 260  
245 261 def OnStartSeed(self, pubsub_evt):
246 262 index = pubsub_evt.data
... ... @@ -321,6 +337,7 @@ class Viewer(wx.Panel):
321 337 if (volumes.GetNumberOfItems()):
322 338 self.ren.RemoveVolume(volumes.GetLastProp())
323 339 self.interactor.Render()
  340 + self._to_show_ball -= 1
324 341  
325 342 def RemoveActors(self, pubsub_evt):
326 343 "Remove a list of actors"
... ... @@ -605,12 +622,16 @@ class Viewer(wx.Panel):
605 622  
606 623 def OnShowRaycasting(self, pubsub_evt):
607 624 self.raycasting_volume = True
  625 + self._to_show_ball += 1
  626 + print "to show ball", self._to_show_ball
608 627 if self.on_wl:
609 628 self.text.Show()
610 629  
611 630 def OnHideRaycasting(self, pubsub_evt):
612 631 self.raycasting_volume = False
613 632 self.text.Hide()
  633 + self._to_show_ball -= 1
  634 + print "to show ball", self._to_show_ball
614 635  
615 636 def OnSize(self, evt):
616 637 self.UpdateRender()
... ... @@ -639,6 +660,8 @@ class Viewer(wx.Panel):
639 660  
640 661 #self.ShowOrientationCube()
641 662 self.interactor.Render()
  663 + self._to_show_ball += 1
  664 + print "to show ball", self._to_show_ball
642 665  
643 666 def RemoveActor(self, pubsub_evt):
644 667 utils.debug("RemoveActor")
... ... @@ -646,6 +669,8 @@ class Viewer(wx.Panel):
646 669 ren = self.ren
647 670 ren.RemoveActor(actor)
648 671 self.interactor.Render()
  672 + #self._to_show_ball -= 1
  673 + #print "to show ball", self._to_show_ball
649 674  
650 675 def RemoveAllActor(self, pubsub_evt):
651 676 utils.debug("RemoveAllActor")
... ... @@ -658,6 +683,8 @@ class Viewer(wx.Panel):
658 683  
659 684 def LoadVolume(self, pubsub_evt):
660 685 self.raycasting_volume = True
  686 + #self._to_show_ball += 1
  687 + #print "to show ball", self._to_show_ball
661 688  
662 689 volume = pubsub_evt.data[0]
663 690 colour = pubsub_evt.data[1]
... ... @@ -685,7 +712,10 @@ class Viewer(wx.Panel):
685 712  
686 713 def UnloadVolume(self, pubsub_evt):
687 714 volume = pubsub_evt.data
  715 + self._to_show_ball -= 1
688 716 self.ren.RemoveVolume(volume)
  717 + del volume
  718 + print "to show ball", self._to_show_ball
689 719  
690 720 def OnSetViewAngle(self, evt_pubsub):
691 721 view = evt_pubsub.data
... ... @@ -824,6 +854,9 @@ class Viewer(wx.Panel):
824 854 self.SetViewAngle(const.VOL_ISO)
825 855 self.repositioned_coronal_plan = 1
826 856  
  857 + def _verify_necessity_ball_ref(self):
  858 + pass
  859 +
827 860  
828 861  
829 862  
... ...
invesalius/data/volume.py
... ... @@ -18,6 +18,7 @@
18 18 #--------------------------------------------------------------------------
19 19 import plistlib
20 20 import os
  21 +import weakref
21 22  
22 23 import numpy
23 24 import vtk
... ... @@ -173,12 +174,30 @@ class Volume():
173 174 #Publisher.sendMessage('Render volume viewer')
174 175 else:
175 176 self.LoadVolume()
176   - self.CalculateHistogram()
  177 + #self.CalculateHistogram()
177 178 self.exist = 1
178 179  
179 180 colour = self.GetBackgroundColour()
180 181 Publisher.sendMessage('Change volume viewer background colour', colour)
181 182 Publisher.sendMessage('Change volume viewer gui colour', colour)
  183 + else:
  184 + Publisher.sendMessage('Unload volume', self.volume)
  185 + del self.image
  186 + del self.imagedata
  187 + del self.final_imagedata
  188 + del self.volume
  189 + del self.color_transfer
  190 + del self.opacity_transfer_func
  191 + del self.volume_properties
  192 + del self.volume_mapper
  193 + self.volume = None
  194 + self.exist = False
  195 + self.loaded_image = False
  196 + self.image = None
  197 + self.final_imagedata = None
  198 + self.opacity_transfer_func = None
  199 + self.color_transfer = None
  200 + Publisher.sendMessage('Render volume viewer')
182 201  
183 202 def OnFlipVolume(self, pubsub_evt):
184 203 print "Flipping Volume"
... ... @@ -198,7 +217,6 @@ class Volume():
198 217 self.Create8bColorTable(self.scale)
199 218 self.Create8bOpacityTable(self.scale)
200 219  
201   -
202 220 def __load_preset(self):
203 221 # Update colour table
204 222 self.__update_colour_table()
... ... @@ -212,7 +230,6 @@ class Volume():
212 230 self.SetShading()
213 231 self.SetTypeRaycasting()
214 232  
215   -
216 233 def OnSetCurve(self, pubsub_evt):
217 234 self.curve = pubsub_evt.data
218 235 self.CalculateWWWL()
... ... @@ -469,9 +486,16 @@ class Volume():
469 486 convolve = vtk.vtkImageConvolve()
470 487 convolve.SetInput(imagedata)
471 488 convolve.SetKernel5x5([i/60.0 for i in Kernels[filter]])
472   - convolve.AddObserver("ProgressEvent", lambda obj,evt:
473   - update_progress(convolve, "Rendering..."))
  489 + convolve.ReleaseDataFlagOn()
  490 +
  491 + convolve_ref = weakref.ref(convolve)
  492 +
  493 + convolve_ref().AddObserver("ProgressEvent", lambda obj,evt:
  494 + update_progress(convolve_ref(), "Rendering..."))
  495 + convolve.Update()
  496 + del imagedata
474 497 imagedata = convolve.GetOutput()
  498 + del convolve
475 499 #convolve.GetOutput().ReleaseDataFlagOn()
476 500 return imagedata
477 501  
... ... @@ -509,12 +533,13 @@ class Volume():
509 533 flip.SetInput(image)
510 534 flip.SetFilteredAxis(1)
511 535 flip.FlipAboutOriginOn()
512   - flip.AddObserver("ProgressEvent", lambda obj,evt:
513   - update_progress(flip, "Rendering..."))
  536 + flip.ReleaseDataFlagOn()
  537 +
  538 + flip_ref = weakref.ref(flip)
  539 + flip_ref().AddObserver("ProgressEvent", lambda obj,evt:
  540 + update_progress(flip_ref(), "Rendering..."))
514 541 flip.Update()
515 542 image = flip.GetOutput()
516   - #else:
517   - #update_progress= vtk_utils.ShowProgress(1 + number_filters)
518 543  
519 544 scale = image.GetScalarRange()
520 545 self.scale = scale
... ... @@ -523,10 +548,13 @@ class Volume():
523 548 cast.SetInput(image)
524 549 cast.SetShift(abs(scale[0]))
525 550 cast.SetOutputScalarTypeToUnsignedShort()
526   - cast.AddObserver("ProgressEvent", lambda obj,evt:
527   - update_progress(cast, "Rendering..."))
  551 + cast.ReleaseDataFlagOn()
  552 + cast_ref = weakref.ref(cast)
  553 + cast_ref().AddObserver("ProgressEvent", lambda obj,evt:
  554 + update_progress(cast_ref(), "Rendering..."))
528 555 cast.Update()
529 556 image2 = cast
  557 +
530 558 self.imagedata = image2
531 559 if self.config['advancedCLUT']:
532 560 self.Create16bColorTable(scale)
... ... @@ -606,6 +634,8 @@ class Volume():
606 634  
607 635 Publisher.sendMessage('Load volume into viewer',
608 636 (volume, colour, (self.ww, self.wl)))
  637 + del flip
  638 + del cast
609 639  
610 640 def OnEnableTool(self, pubsub_evt):
611 641 tool_name, enable = pubsub_evt.data
... ... @@ -630,6 +660,7 @@ class Volume():
630 660 accumulate.SetInput(image)
631 661 accumulate.SetComponentExtent(0, r -1, 0, 0, 0, 0)
632 662 accumulate.SetComponentOrigin(image.GetScalarRange()[0], 0, 0)
  663 + accumulate.ReleaseDataFlagOn()
633 664 accumulate.Update()
634 665 n_image = numpy_support.vtk_to_numpy(accumulate.GetOutput().GetPointData().GetScalars())
635 666 Publisher.sendMessage('Load histogram', (n_image,
... ...