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