Commit e63af012f1c31649c59778351f80ce3e2917b762

Authored by Paulo Henrique Junqueira Amorim
1 parent c899bff4

ENH: Improved progress bar

invesalius/data/surface.py
... ... @@ -377,7 +377,7 @@ class SurfaceManager():
377 377 """
378 378 matrix, filename_img, mask, spacing = pubsub_evt.data
379 379 min_value, max_value = mask.threshold_range
380   - fill_holes = True
  380 + fill_holes = False
381 381  
382 382 #if len(surface_data) == 5:
383 383 #imagedata, colour, [min_value, max_value], \
... ... @@ -394,7 +394,7 @@ class SurfaceManager():
394 394  
395 395 mode = 'CONTOUR' # 'GRAYSCALE'
396 396 quality=_('Optimal *')
397   - keep_largest = True
  397 + keep_largest = False
398 398 surface_name = ""
399 399 colour = mask.colour
400 400  
... ... @@ -415,19 +415,19 @@ class SurfaceManager():
415 415 #if imagedata_resolution:
416 416 #imagedata = iu.ResampleImage3D(imagedata, imagedata_resolution)
417 417  
418   - #pipeline_size = 4
419   - #if decimate_reduction:
420   - #pipeline_size += 1
421   - #if (smooth_iterations and smooth_relaxation_factor):
422   - #pipeline_size += 1
  418 + pipeline_size = 4
  419 + if decimate_reduction:
  420 + pipeline_size += 1
  421 + if (smooth_iterations and smooth_relaxation_factor):
  422 + pipeline_size += 1
423 423 #if fill_holes:
424   - #pipeline_size += 1
  424 + # pipeline_size += 1
425 425 #if keep_largest:
426   - #pipeline_size += 1
427   -
  426 + # pipeline_size += 1
  427 +
428 428 ## Update progress value in GUI
429   - #UpdateProgress = vu.ShowProgress(pipeline_size)
430   - #UpdateProgress(0, _("Generating 3D surface..."))
  429 + UpdateProgress = vu.ShowProgress(pipeline_size)
  430 + UpdateProgress(0, _("Generating 3D surface..."))
431 431  
432 432 #filename_img = tempfile.mktemp()
433 433  
... ... @@ -452,7 +452,6 @@ class SurfaceManager():
452 452 piece_size = 20
453 453  
454 454 n_pieces = int(round(matrix.shape[0] / piece_size + 0.5, 0))
455   - print "n_pieces", n_pieces, matrix.shape
456 455  
457 456 q_in = multiprocessing.Queue()
458 457 q_out = multiprocessing.Queue()
... ... @@ -463,8 +462,7 @@ class SurfaceManager():
463 462 matrix.shape, matrix.dtype, spacing,
464 463 mode, min_value, max_value,
465 464 decimate_reduction, smooth_relaxation_factor,
466   - smooth_iterations, language, fill_holes, keep_largest,
467   - flip_image, q_in, q_out)
  465 + smooth_iterations, language, flip_image, q_in, q_out)
468 466 p.append(sp)
469 467 sp.start()
470 468  
... ... @@ -478,6 +476,18 @@ class SurfaceManager():
478 476 for i in p:
479 477 q_in.put(None)
480 478  
  479 + none_count = 1
  480 + while 1:
  481 + msg = pipe_out.recv()
  482 + if(msg is None):
  483 + none_count += 1
  484 + else:
  485 + UpdateProgress(msg[0]/(n_pieces * pipeline_size), msg[1])
  486 +
  487 + if none_count > n_pieces:
  488 + break
  489 +
  490 +
481 491 polydata_append = vtk.vtkAppendPolyData()
482 492 t = n_pieces
483 493 while t:
... ... @@ -490,13 +500,18 @@ class SurfaceManager():
490 500  
491 501 t -= 1
492 502 polydata = polydata_append.GetOutput()
493   -
494 503 clean = vtk.vtkCleanPolyData()
  504 + clean.AddObserver("ProgressEvent", lambda obj,evt:
  505 + UpdateProgress(obj, _("Generating 3D surface...")))
495 506 clean.SetInput(polydata)
496 507 clean.PointMergingOn()
  508 + clean.Update()
497 509 polydata = clean.GetOutput()
498 510  
  511 +
499 512 smoother = vtk.vtkWindowedSincPolyDataFilter()
  513 + smoother.AddObserver("ProgressEvent", lambda obj,evt:
  514 + UpdateProgress(obj, _("Generating 3D surface...")))
500 515 smoother.SetInput(polydata)
501 516 smoother.SetNumberOfIterations(smooth_iterations)
502 517 smoother.SetFeatureAngle(120)
... ... @@ -508,29 +523,48 @@ class SurfaceManager():
508 523 smoother.Update()
509 524 polydata = smoother.GetOutput()
510 525  
  526 + if keep_largest:
  527 + conn = vtk.vtkPolyDataConnectivityFilter()
  528 + conn.SetInput(polydata)
  529 + conn.SetExtractionModeToLargestRegion()
  530 + conn.AddObserver("ProgressEvent", lambda obj,evt:
  531 + UpdateProgress(obj, _("Generating 3D surface...")))
  532 + polydata = conn.GetOutput()
  533 +
  534 +
  535 + # Filter used to detect and fill holes. Only fill boundary edges holes.
  536 + #TODO: Hey! This piece of code is the same from
  537 + # polydata_utils.FillSurfaceHole, we need to review this.
  538 + if fill_holes:
  539 + filled_polydata = vtk.vtkFillHolesFilter()
  540 + filled_polydata.SetInput(polydata)
  541 + filled_polydata.SetHoleSize(300)
  542 + #filled_polydata.AddObserver("ProgressEvent", lambda obj,evt:
  543 + # UpdateProgress(obj, _("Generating 3D surface...")))
  544 + polydata = filled_polydata.GetOutput()
511 545  
512 546 normals = vtk.vtkPolyDataNormals()
  547 + normals.AddObserver("ProgressEvent", lambda obj,evt:
  548 + UpdateProgress(obj, _("Generating 3D surface...")))
513 549 normals.SetInput(polydata)
514 550 normals.SetFeatureAngle(80)
515 551 normals.AutoOrientNormalsOn()
  552 + normals.Update()
516 553 polydata = normals.GetOutput()
517   - #decimation = vtk.vtkDecimatePro()
518   - #decimation.SetInput(polydata)
519   - #decimation.SetTargetReduction(0.3)
520   - #decimation.PreserveTopologyOn()
521   - #decimation.SplittingOff()
522   - #decimation.BoundaryVertexDeletionOff()
523   - #polydata = decimation.GetOutput()
524 554  
525 555 # Improve performance
526 556 stripper = vtk.vtkStripper()
  557 + stripper.AddObserver("ProgressEvent", lambda obj,evt:
  558 + UpdateProgress(obj, _("Generating 3D surface...")))
527 559 stripper.SetInput(polydata)
528 560 stripper.PassThroughCellIdsOn()
529 561 stripper.PassThroughPointIdsOn()
  562 + stripper.Update()
  563 + polydata = stripper.GetOutput()
530 564  
531 565 # Map polygonal data (vtkPolyData) to graphics primitives.
532 566 mapper = vtk.vtkPolyDataMapper()
533   - mapper.SetInput(stripper.GetOutput())
  567 + mapper.SetInput(polydata)
534 568 mapper.ScalarVisibilityOff()
535 569 mapper.ImmediateModeRenderingOn() # improve performance
536 570  
... ... @@ -601,15 +635,16 @@ class SurfaceManager():
601 635 # Save actor for future management tasks
602 636 self.actors_dict[surface.index] = actor
603 637  
604   -
605   - ps.Publisher().sendMessage('Update status text in GUI',
606   - _("Ready"))
607   -
608 638 ps.Publisher().sendMessage('Update surface info in GUI',
609 639 (surface.index, surface.name,
610 640 surface.colour, surface.volume,
611 641 surface.transparency))
612 642  
  643 + UpdateProgress(0, _("Ready"))
  644 + UpdateProgress(0, _("Ready"))
  645 + ps.Publisher().sendMessage('Update status text in GUI',
  646 + _("Ready"))
  647 +
613 648 ps.Publisher().sendMessage('End busy cursor')
614 649  
615 650  
... ...
invesalius/data/surface_process.py
... ... @@ -13,8 +13,7 @@ class SurfaceProcess(multiprocessing.Process):
13 13  
14 14 def __init__(self, pipe, filename, shape, dtype, spacing, mode, min_value, max_value,
15 15 decimate_reduction, smooth_relaxation_factor,
16   - smooth_iterations, language, fill_holes, keep_largest,
17   - flip_image, q_in, q_out):
  16 + smooth_iterations, language, flip_image, q_in, q_out):
18 17  
19 18 multiprocessing.Process.__init__(self)
20 19 self.pipe = pipe
... ... @@ -27,8 +26,6 @@ class SurfaceProcess(multiprocessing.Process):
27 26 self.smooth_relaxation_factor = smooth_relaxation_factor
28 27 self.smooth_iterations = smooth_iterations
29 28 self.language = language
30   - self.fill_holes = fill_holes
31   - self.keep_largest = keep_largest
32 29 self.flip_image = flip_image
33 30 self.q_in = q_in
34 31 self.q_out = q_out
... ... @@ -40,7 +37,6 @@ class SurfaceProcess(multiprocessing.Process):
40 37 shape=self.shape)
41 38 while 1:
42 39 roi = self.q_in.get()
43   - print roi
44 40 if roi is None:
45 41 break
46 42 self.CreateSurface(roi)
... ... @@ -60,77 +56,52 @@ class SurfaceProcess(multiprocessing.Process):
60 56 flip.Update()
61 57 # Create vtkPolyData from vtkImageData
62 58 #print "Generating Polydata"
63   - #if self.mode == "CONTOUR":
  59 + if self.mode == "CONTOUR":
64 60 #print "Contour"
65   - #contour = vtk.vtkContourFilter()
66   - #contour.SetInput(image)
67   - #contour.SetValue(0, self.min_value) # initial threshold
68   - #contour.SetValue(1, self.max_value) # final threshold
69   - #contour.ComputeScalarsOn()
70   - #contour.ComputeGradientsOn()
71   - #contour.ComputeNormalsOn()
72   - #polydata = contour.GetOutput()
73   - #else: #mode == "GRAYSCALE":
74   - mcubes = vtk.vtkMarchingCubes()
75   - mcubes.SetInput(flip.GetOutput())
76   - mcubes.SetValue(0, self.min_value)
77   - mcubes.SetValue(1, self.max_value)
78   - mcubes.ComputeScalarsOff()
79   - mcubes.ComputeGradientsOff()
80   - mcubes.ComputeNormalsOff()
81   - polydata = mcubes.GetOutput()
  61 + contour = vtk.vtkContourFilter()
  62 + contour.SetInput(flip.GetOutput())
  63 + contour.SetValue(0, self.min_value) # initial threshold
  64 + contour.SetValue(1, self.max_value) # final threshold
  65 + contour.ComputeScalarsOn()
  66 + contour.ComputeGradientsOn()
  67 + contour.ComputeNormalsOn()
  68 + contour.AddObserver("ProgressEvent", lambda obj,evt:
  69 + self.SendProgress(obj, _("Generating 3D surface...")))
  70 + polydata = contour.GetOutput()
  71 + else: #mode == "GRAYSCALE":
  72 + mcubes = vtk.vtkMarchingCubes()
  73 + mcubes.SetInput(flip.GetOutput())
  74 + mcubes.SetValue(0, self.min_value)
  75 + mcubes.SetValue(1, self.max_value)
  76 + mcubes.ComputeScalarsOff()
  77 + mcubes.ComputeGradientsOff()
  78 + mcubes.ComputeNormalsOff()
  79 + mcubes.AddObserver("ProgressEvent", lambda obj,evt:
  80 + self.SendProgress(obj, _("Generating 3D surface...")))
  81 + polydata = mcubes.GetOutput()
82 82  
83 83 triangle = vtk.vtkTriangleFilter()
84 84 triangle.SetInput(polydata)
  85 + triangle.AddObserver("ProgressEvent", lambda obj,evt:
  86 + self.SendProgress(obj, _("Generating 3D surface...")))
85 87 triangle.Update()
86 88 polydata = triangle.GetOutput()
87 89  
88   - bounds = polydata.GetBounds()
89   - origin = ((bounds[1] + bounds[0]) / 2.0, (bounds[3] + bounds[2])/2.0,
90   - (bounds[5] + bounds[4]) / 2.0)
91   -
92   - print "Bounds is", bounds
93   - print "origin is", origin
94   -
95   - #print "Decimating"
96   - decimation = vtk.vtkDecimatePro()
97   - decimation.SetInput(polydata)
98   - decimation.SetTargetReduction(0.3)
99   - #decimation.PreserveTopologyOn()
100   - decimation.SplittingOff()
101   - decimation.BoundaryVertexDeletionOff()
102   - polydata = decimation.GetOutput()
103   -
104   - #decimation = vtk.vtkQuadricClustering()
105   - #decimation.SetInput(polydata)
106   - #decimation.AutoAdjustNumberOfDivisionsOff()
107   - #decimation.SetDivisionOrigin(0, 0, 0)
108   - #decimation.SetDivisionSpacing(self.spacing)
109   - #decimation.SetFeaturePointsAngle(80)
110   - #decimation.UseFeaturePointsOn()
111   - #decimation.UseFeatureEdgesOn()
112   - #ecimation.CopyCellDataOn()
  90 + if self.decimate_reduction:
  91 +
  92 + #print "Decimating"
  93 + decimation = vtk.vtkDecimatePro()
  94 + decimation.SetInput(polydata)
  95 + decimation.SetTargetReduction(0.3)
  96 + decimation.AddObserver("ProgressEvent", lambda obj,evt:
  97 + self.SendProgress(obj, _("Generating 3D surface...")))
  98 + #decimation.PreserveTopologyOn()
  99 + decimation.SplittingOff()
  100 + decimation.BoundaryVertexDeletionOff()
  101 + polydata = decimation.GetOutput()
  102 +
  103 + self.pipe.send(None)
113 104  
114   - #print "Division", decimation.GetNumberOfDivisions()
115   -
116   - #polydata = decimation.GetOutput()
117   -
118   - #if self.smooth_iterations and self.smooth_relaxation_factor:
119   - #print "Smoothing"
120   - #smoother = vtk.vtkWindowedSincPolyDataFilter()
121   - #smoother.SetInput(polydata)
122   - #smoother.SetNumberOfIterations(self.smooth_iterations)
123   - #smoother.SetFeatureAngle(120)
124   - #smoother.SetNumberOfIterations(30)
125   - #smoother.BoundarySmoothingOn()
126   - #smoother.SetPassBand(0.01)
127   - #smoother.FeatureEdgeSmoothingOn()
128   - #smoother.NonManifoldSmoothingOn()
129   - #smoother.NormalizeCoordinatesOn()
130   - #smoother.Update()
131   - #polydata = smoother.GetOutput()
132   -
133   - print "Saving"
134 105 filename = tempfile.mktemp(suffix='_%s.vtp' % (self.pid))
135 106 writer = vtk.vtkXMLPolyDataWriter()
136 107 writer.SetInput(polydata)
... ...
invesalius/data/vtk_utils.py
... ... @@ -74,7 +74,6 @@ def ShowProgress(number_of_filters = 1,
74 74  
75 75 # final progress status value
76 76 progress[0] = progress[0] + ratio*difference
77   -
78 77 # Tell GUI to update progress status value
79 78 if (dialog_type == "GaugeProgress"):
80 79 ps.Publisher().sendMessage('Update status in GUI',
... ...