Commit cc5b70237c7104422a5c9ee70f37a7893367a2ad

Authored by tfmoraes
1 parent 876d77a4

Fixed some memory leaks when generating a surface

invesalius/data/surface.py
@@ -21,6 +21,7 @@ import multiprocessing @@ -21,6 +21,7 @@ import multiprocessing
21 import os 21 import os
22 import plistlib 22 import plistlib
23 import random 23 import random
  24 +import weakref
24 25
25 import vtk 26 import vtk
26 import wx 27 import wx
@@ -474,132 +475,207 @@ class SurfaceManager(): @@ -474,132 +475,207 @@ class SurfaceManager():
474 break 475 break
475 476
476 polydata_append = vtk.vtkAppendPolyData() 477 polydata_append = vtk.vtkAppendPolyData()
  478 + polydata_append.ReleaseDataFlagOn()
477 t = n_pieces 479 t = n_pieces
478 while t: 480 while t:
479 filename_polydata = q_out.get() 481 filename_polydata = q_out.get()
480 482
481 reader = vtk.vtkXMLPolyDataReader() 483 reader = vtk.vtkXMLPolyDataReader()
482 reader.SetFileName(filename_polydata) 484 reader.SetFileName(filename_polydata)
  485 + reader.ReleaseDataFlagOn()
483 reader.Update() 486 reader.Update()
484 - polydata_append.AddInput(reader.GetOutput()) 487 + reader.GetOutput().ReleaseDataFlagOn()
  488 +
  489 + polydata = reader.GetOutput()
  490 + polydata.SetSource(None)
  491 +
  492 + polydata_append.AddInput(polydata)
  493 + del reader
  494 + del polydata
485 t -= 1 495 t -= 1
486 496
487 polydata_append.Update() 497 polydata_append.Update()
  498 + polydata_append.GetOutput().ReleaseDataFlagOn()
488 polydata = polydata_append.GetOutput() 499 polydata = polydata_append.GetOutput()
  500 + #polydata.Register(None)
  501 + polydata.SetSource(None)
  502 + del polydata_append
489 503
490 if algorithm == u'Context aware smoothing': 504 if algorithm == u'Context aware smoothing':
491 normals = vtk.vtkPolyDataNormals() 505 normals = vtk.vtkPolyDataNormals()
492 - normals.AddObserver("ProgressEvent", lambda obj,evt:  
493 - UpdateProgress(obj, _("Generating 3D surface..."))) 506 + normals_ref = weakref.ref(normals)
  507 + normals_ref().AddObserver("ProgressEvent", lambda obj,evt:
  508 + UpdateProgress(normals_ref(), _("Generating 3D surface...")))
494 normals.SetInput(polydata) 509 normals.SetInput(polydata)
  510 + normals.ReleaseDataFlagOn()
495 #normals.SetFeatureAngle(80) 511 #normals.SetFeatureAngle(80)
496 #normals.AutoOrientNormalsOn() 512 #normals.AutoOrientNormalsOn()
497 normals.ComputeCellNormalsOn() 513 normals.ComputeCellNormalsOn()
  514 + normals.GetOutput().ReleaseDataFlagOn()
498 normals.Update() 515 normals.Update()
  516 + del polydata
499 polydata = normals.GetOutput() 517 polydata = normals.GetOutput()
  518 + polydata.SetSource(None)
  519 + del normals
500 520
501 clean = vtk.vtkCleanPolyData() 521 clean = vtk.vtkCleanPolyData()
502 - clean.AddObserver("ProgressEvent", lambda obj,evt:  
503 - UpdateProgress(obj, _("Generating 3D surface..."))) 522 + clean.ReleaseDataFlagOn()
  523 + clean.GetOutput().ReleaseDataFlagOn()
  524 + clean_ref = weakref.ref(clean)
  525 + clean_ref().AddObserver("ProgressEvent", lambda obj,evt:
  526 + UpdateProgress(clean_ref(), _("Generating 3D surface...")))
504 clean.SetInput(polydata) 527 clean.SetInput(polydata)
505 clean.PointMergingOn() 528 clean.PointMergingOn()
506 clean.Update() 529 clean.Update()
  530 +
  531 + del polydata
507 polydata = clean.GetOutput() 532 polydata = clean.GetOutput()
  533 + polydata.SetSource(None)
  534 + del clean
508 535
509 polydata.BuildLinks() 536 polydata.BuildLinks()
510 polydata = ca_smoothing.ca_smoothing(polydata, options['angle'], 537 polydata = ca_smoothing.ca_smoothing(polydata, options['angle'],
511 options['max distance'], 538 options['max distance'],
512 options['min weight'], 539 options['min weight'],
513 options['steps']) 540 options['steps'])
  541 + polydata.SetSource(None)
  542 + polydata.DebugOn()
514 543
515 else: 544 else:
516 smoother = vtk.vtkWindowedSincPolyDataFilter() 545 smoother = vtk.vtkWindowedSincPolyDataFilter()
517 - smoother.AddObserver("ProgressEvent", lambda obj,evt:  
518 - UpdateProgress(obj, _("Generating 3D surface..."))) 546 + smoother_ref = weakref.ref(smoother)
  547 + smoother_ref().AddObserver("ProgressEvent", lambda obj,evt:
  548 + UpdateProgress(smoother_ref(), _("Generating 3D surface...")))
519 smoother.SetInput(polydata) 549 smoother.SetInput(polydata)
520 smoother.SetNumberOfIterations(smooth_iterations) 550 smoother.SetNumberOfIterations(smooth_iterations)
521 smoother.SetFeatureAngle(120) 551 smoother.SetFeatureAngle(120)
522 smoother.SetEdgeAngle(90.0) 552 smoother.SetEdgeAngle(90.0)
523 smoother.BoundarySmoothingOn() 553 smoother.BoundarySmoothingOn()
524 smoother.SetPassBand(0.1) 554 smoother.SetPassBand(0.1)
  555 + smoother.ReleaseDataFlagOn()
  556 + smoother.GetOutput().ReleaseDataFlagOn()
525 #smoother.FeatureEdgeSmoothingOn() 557 #smoother.FeatureEdgeSmoothingOn()
526 #smoother.NonManifoldSmoothingOn() 558 #smoother.NonManifoldSmoothingOn()
527 #smoother.NormalizeCoordinatesOn() 559 #smoother.NormalizeCoordinatesOn()
528 smoother.Update() 560 smoother.Update()
  561 + del polydata
529 polydata = smoother.GetOutput() 562 polydata = smoother.GetOutput()
  563 + #polydata.Register(None)
  564 + polydata.SetSource(None)
  565 + del smoother
530 566
531 567
532 if decimate_reduction: 568 if decimate_reduction:
533 print "Decimating", decimate_reduction 569 print "Decimating", decimate_reduction
534 decimation = vtk.vtkQuadricDecimation() 570 decimation = vtk.vtkQuadricDecimation()
  571 + decimation.ReleaseDataFlagOn()
535 decimation.SetInput(polydata) 572 decimation.SetInput(polydata)
536 decimation.SetTargetReduction(decimate_reduction) 573 decimation.SetTargetReduction(decimate_reduction)
537 - decimation.AddObserver("ProgressEvent", lambda obj,evt:  
538 - UpdateProgress(obj, _("Generating 3D surface..."))) 574 + decimation_ref = weakref.ref(decimation)
  575 + decimation_ref().AddObserver("ProgressEvent", lambda obj,evt:
  576 + UpdateProgress(decimation_ref(), _("Generating 3D surface...")))
539 #decimation.PreserveTopologyOn() 577 #decimation.PreserveTopologyOn()
540 #decimation.SplittingOff() 578 #decimation.SplittingOff()
541 #decimation.BoundaryVertexDeletionOff() 579 #decimation.BoundaryVertexDeletionOff()
  580 + decimation.GetOutput().ReleaseDataFlagOn()
542 decimation.Update() 581 decimation.Update()
  582 + del polydata
543 polydata = decimation.GetOutput() 583 polydata = decimation.GetOutput()
  584 + #polydata.Register(None)
  585 + polydata.SetSource(None)
  586 + del decimation
544 587
545 to_measure = polydata 588 to_measure = polydata
  589 + #to_measure.Register(None)
  590 + to_measure.SetSource(None)
546 591
547 if keep_largest: 592 if keep_largest:
548 conn = vtk.vtkPolyDataConnectivityFilter() 593 conn = vtk.vtkPolyDataConnectivityFilter()
549 conn.SetInput(polydata) 594 conn.SetInput(polydata)
550 conn.SetExtractionModeToLargestRegion() 595 conn.SetExtractionModeToLargestRegion()
551 - conn.AddObserver("ProgressEvent", lambda obj,evt:  
552 - UpdateProgress(obj, _("Generating 3D surface..."))) 596 + conn_ref = weakref.ref(conn)
  597 + conn_ref().AddObserver("ProgressEvent", lambda obj,evt:
  598 + UpdateProgress(conn_ref(), _("Generating 3D surface...")))
553 conn.Update() 599 conn.Update()
  600 + conn.GetOutput().ReleaseDataFlagOn()
  601 + del polydata
554 polydata = conn.GetOutput() 602 polydata = conn.GetOutput()
  603 + #polydata.Register(None)
  604 + polydata.SetSource(None)
  605 + del conn
555 606
556 #Filter used to detect and fill holes. Only fill boundary edges holes. 607 #Filter used to detect and fill holes. Only fill boundary edges holes.
557 #TODO: Hey! This piece of code is the same from 608 #TODO: Hey! This piece of code is the same from
558 #polydata_utils.FillSurfaceHole, we need to review this. 609 #polydata_utils.FillSurfaceHole, we need to review this.
559 if fill_holes: 610 if fill_holes:
560 filled_polydata = vtk.vtkFillHolesFilter() 611 filled_polydata = vtk.vtkFillHolesFilter()
  612 + filled_polydata.ReleaseDataFlagOn()
561 filled_polydata.SetInput(polydata) 613 filled_polydata.SetInput(polydata)
562 filled_polydata.SetHoleSize(300) 614 filled_polydata.SetHoleSize(300)
563 - filled_polydata.AddObserver("ProgressEvent", lambda obj,evt:  
564 - UpdateProgress(obj, _("Generating 3D surface..."))) 615 + filled_polydata_ref = weakref.ref(filled_polydata)
  616 + filled_polydata_ref().AddObserver("ProgressEvent", lambda obj,evt:
  617 + UpdateProgress(filled_polydata_ref(), _("Generating 3D surface...")))
565 filled_polydata.Update() 618 filled_polydata.Update()
  619 + filled_polydata.GetOutput().ReleaseDataFlagOn()
  620 + del polydata
566 polydata = filled_polydata.GetOutput() 621 polydata = filled_polydata.GetOutput()
  622 + #polydata.Register(None)
  623 + polydata.SetSource(None)
  624 + polydata.DebugOn()
  625 + del filled_polydata
567 626
568 normals = vtk.vtkPolyDataNormals() 627 normals = vtk.vtkPolyDataNormals()
569 - normals.AddObserver("ProgressEvent", lambda obj,evt:  
570 - UpdateProgress(obj, _("Generating 3D surface..."))) 628 + normals.ReleaseDataFlagOn()
  629 + normals_ref = weakref.ref(normals)
  630 + normals_ref().AddObserver("ProgressEvent", lambda obj,evt:
  631 + UpdateProgress(normals_ref(), _("Generating 3D surface...")))
571 normals.SetInput(polydata) 632 normals.SetInput(polydata)
572 normals.SetFeatureAngle(80) 633 normals.SetFeatureAngle(80)
573 normals.AutoOrientNormalsOn() 634 normals.AutoOrientNormalsOn()
  635 + normals.GetOutput().ReleaseDataFlagOn()
574 normals.Update() 636 normals.Update()
  637 + del polydata
575 polydata = normals.GetOutput() 638 polydata = normals.GetOutput()
  639 + #polydata.Register(None)
  640 + polydata.SetSource(None)
  641 + del normals
576 642
577 # Improve performance 643 # Improve performance
578 stripper = vtk.vtkStripper() 644 stripper = vtk.vtkStripper()
579 - stripper.AddObserver("ProgressEvent", lambda obj,evt:  
580 - UpdateProgress(obj, _("Generating 3D surface..."))) 645 + stripper.ReleaseDataFlagOn()
  646 + stripper_ref = weakref.ref(stripper)
  647 + stripper_ref().AddObserver("ProgressEvent", lambda obj,evt:
  648 + UpdateProgress(stripper_ref(), _("Generating 3D surface...")))
581 stripper.SetInput(polydata) 649 stripper.SetInput(polydata)
582 stripper.PassThroughCellIdsOn() 650 stripper.PassThroughCellIdsOn()
583 stripper.PassThroughPointIdsOn() 651 stripper.PassThroughPointIdsOn()
  652 + stripper.GetOutput().ReleaseDataFlagOn()
584 stripper.Update() 653 stripper.Update()
  654 + del polydata
585 polydata = stripper.GetOutput() 655 polydata = stripper.GetOutput()
  656 + #polydata.Register(None)
  657 + polydata.SetSource(None)
  658 + del stripper
586 659
587 # Map polygonal data (vtkPolyData) to graphics primitives. 660 # Map polygonal data (vtkPolyData) to graphics primitives.
588 mapper = vtk.vtkPolyDataMapper() 661 mapper = vtk.vtkPolyDataMapper()
589 mapper.SetInput(polydata) 662 mapper.SetInput(polydata)
590 mapper.ScalarVisibilityOff() 663 mapper.ScalarVisibilityOff()
  664 + mapper.ReleaseDataFlagOn()
591 mapper.ImmediateModeRenderingOn() # improve performance 665 mapper.ImmediateModeRenderingOn() # improve performance
592 666
593 # Represent an object (geometry & properties) in the rendered scene 667 # Represent an object (geometry & properties) in the rendered scene
594 actor = vtk.vtkActor() 668 actor = vtk.vtkActor()
595 actor.SetMapper(mapper) 669 actor.SetMapper(mapper)
596 - # Create Surface instance 670 + del mapper
  671 + #Create Surface instance
597 if overwrite: 672 if overwrite:
598 surface = Surface(index = self.last_surface_index) 673 surface = Surface(index = self.last_surface_index)
599 else: 674 else:
600 surface = Surface(name=surface_name) 675 surface = Surface(name=surface_name)
601 surface.colour = colour 676 surface.colour = colour
602 surface.polydata = polydata 677 surface.polydata = polydata
  678 + del polydata
603 679
604 # Set actor colour and transparency 680 # Set actor colour and transparency
605 actor.GetProperty().SetColor(colour) 681 actor.GetProperty().SetColor(colour)
@@ -624,10 +700,13 @@ class SurfaceManager(): @@ -624,10 +700,13 @@ class SurfaceManager():
624 700
625 # The following lines have to be here, otherwise all volumes disappear 701 # The following lines have to be here, otherwise all volumes disappear
626 measured_polydata = vtk.vtkMassProperties() 702 measured_polydata = vtk.vtkMassProperties()
  703 + measured_polydata.ReleaseDataFlagOn()
627 measured_polydata.SetInput(to_measure) 704 measured_polydata.SetInput(to_measure)
628 - volume = measured_polydata.GetVolume() 705 + volume = float(measured_polydata.GetVolume())
629 surface.volume = volume 706 surface.volume = volume
630 self.last_surface_index = surface.index 707 self.last_surface_index = surface.index
  708 + del measured_polydata
  709 + del to_measure
631 710
632 Publisher.sendMessage('Load surface actor into viewer', actor) 711 Publisher.sendMessage('Load surface actor into viewer', actor)
633 712
@@ -647,10 +726,10 @@ class SurfaceManager(): @@ -647,10 +726,10 @@ class SurfaceManager():
647 #When you finalize the progress. The bar is cleaned. 726 #When you finalize the progress. The bar is cleaned.
648 UpdateProgress = vu.ShowProgress(1) 727 UpdateProgress = vu.ShowProgress(1)
649 UpdateProgress(0, _("Ready")) 728 UpdateProgress(0, _("Ready"))
650 - Publisher.sendMessage('Update status text in GUI',  
651 - _("Ready")) 729 + Publisher.sendMessage('Update status text in GUI', _("Ready"))
652 730
653 Publisher.sendMessage('End busy cursor') 731 Publisher.sendMessage('End busy cursor')
  732 + del actor
654 733
655 def UpdateSurfaceInterpolation(self, pub_evt): 734 def UpdateSurfaceInterpolation(self, pub_evt):
656 interpolation = int(ses.Session().surface_interpolation) 735 interpolation = int(ses.Session().surface_interpolation)
invesalius/data/surface_process.py
@@ -52,7 +52,6 @@ class SurfaceProcess(multiprocessing.Process): @@ -52,7 +52,6 @@ class SurfaceProcess(multiprocessing.Process):
52 dtype=self.mask_dtype, 52 dtype=self.mask_dtype,
53 shape=self.mask_shape) 53 shape=self.mask_shape)
54 54
55 -  
56 while 1: 55 while 1:
57 roi = self.q_in.get() 56 roi = self.q_in.get()
58 if roi is None: 57 if roi is None:
@@ -69,6 +68,7 @@ class SurfaceProcess(multiprocessing.Process): @@ -69,6 +68,7 @@ class SurfaceProcess(multiprocessing.Process):
69 1:, 1:]) 68 1:, 1:])
70 image = converters.to_vtk(a_mask, self.spacing, roi.start, 69 image = converters.to_vtk(a_mask, self.spacing, roi.start,
71 "AXIAL") 70 "AXIAL")
  71 + del a_mask
72 else: 72 else:
73 a_image = numpy.array(self.image[roi]) 73 a_image = numpy.array(self.image[roi])
74 74
@@ -84,20 +84,28 @@ class SurfaceProcess(multiprocessing.Process): @@ -84,20 +84,28 @@ class SurfaceProcess(multiprocessing.Process):
84 gauss = vtk.vtkImageGaussianSmooth() 84 gauss = vtk.vtkImageGaussianSmooth()
85 gauss.SetInput(image) 85 gauss.SetInput(image)
86 gauss.SetRadiusFactor(0.3) 86 gauss.SetRadiusFactor(0.3)
  87 + gauss.ReleaseDataFlagOn()
87 gauss.Update() 88 gauss.Update()
88 89
  90 + del image
89 image = gauss.GetOutput() 91 image = gauss.GetOutput()
  92 + del gauss
  93 + del a_mask
90 else: 94 else:
91 image = converters.to_vtk(a_image, self.spacing, roi.start, 95 image = converters.to_vtk(a_image, self.spacing, roi.start,
92 "AXIAL") 96 "AXIAL")
  97 + del a_image
93 98
94 flip = vtk.vtkImageFlip() 99 flip = vtk.vtkImageFlip()
95 flip.SetInput(image) 100 flip.SetInput(image)
96 flip.SetFilteredAxis(1) 101 flip.SetFilteredAxis(1)
97 flip.FlipAboutOriginOn() 102 flip.FlipAboutOriginOn()
  103 + flip.ReleaseDataFlagOn()
98 flip.Update() 104 flip.Update()
99 105
  106 + del image
100 image = flip.GetOutput() 107 image = flip.GetOutput()
  108 + del flip
101 109
102 #filename = tempfile.mktemp(suffix='_%s.vti' % (self.pid)) 110 #filename = tempfile.mktemp(suffix='_%s.vti' % (self.pid))
103 #writer = vtk.vtkXMLImageDataWriter() 111 #writer = vtk.vtkXMLImageDataWriter()
@@ -122,9 +130,14 @@ class SurfaceProcess(multiprocessing.Process): @@ -122,9 +130,14 @@ class SurfaceProcess(multiprocessing.Process):
122 contour.ComputeScalarsOn() 130 contour.ComputeScalarsOn()
123 contour.ComputeGradientsOn() 131 contour.ComputeGradientsOn()
124 contour.ComputeNormalsOn() 132 contour.ComputeNormalsOn()
  133 + contour.ReleaseDataFlagOn()
  134 + contour.Update()
125 #contour.AddObserver("ProgressEvent", lambda obj,evt: 135 #contour.AddObserver("ProgressEvent", lambda obj,evt:
126 # self.SendProgress(obj, _("Generating 3D surface..."))) 136 # self.SendProgress(obj, _("Generating 3D surface...")))
127 polydata = contour.GetOutput() 137 polydata = contour.GetOutput()
  138 + del image
  139 + del contour
  140 +
128 #else: #mode == "GRAYSCALE": 141 #else: #mode == "GRAYSCALE":
129 #mcubes = vtk.vtkMarchingCubes() 142 #mcubes = vtk.vtkMarchingCubes()
130 #mcubes.SetInput(flip.GetOutput()) 143 #mcubes.SetInput(flip.GetOutput())
@@ -166,5 +179,7 @@ class SurfaceProcess(multiprocessing.Process): @@ -166,5 +179,7 @@ class SurfaceProcess(multiprocessing.Process):
166 writer.Write() 179 writer.Write()
167 180
168 print "Writing piece", roi, "to", filename 181 print "Writing piece", roi, "to", filename
  182 + del polydata
  183 + del writer
169 184
170 self.q_out.put(filename) 185 self.q_out.put(filename)