waveletvolume.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import datetime as dt
  2. from paraview import servermanager
  3. from paraview.simple import *
  4. from paraview.benchmark import *
  5. #import logbase, logparser
  6. logbase.maximize_logs()
  7. records = []
  8. n0 = dt.datetime.now()
  9. def get_render_view(size):
  10. '''Similar to GetRenderView except if a new view is created, it's
  11. created with the specified size instead of having t resize afterwards
  12. '''
  13. view = active_objects.view
  14. if not view:
  15. # it's possible that there's no active view, but a render view exists.
  16. # If so, locate that and return it (before trying to create a new one).
  17. view = servermanager.GetRenderView()
  18. if not view:
  19. view = CreateRenderView(ViewSize=size)
  20. return view
  21. def save_render_buffer(fname):
  22. '''Similar to SaveScreenshot except a re-render will not be triggered'''
  23. from vtkmodules.vtkRenderingCore import vtkWindowToImageFilter
  24. w = GetRenderView().SMProxy.GetRenderWindow()
  25. w2i = vtkWindowToImageFilter()
  26. w2i.ReadFrontBufferOff()
  27. w2i.ShouldRerenderOff()
  28. w2i.SetInput(w)
  29. w2i.Modified()
  30. png = PNGWriter()
  31. png.Input = w2i.GetOutput()
  32. png.FileName = fname
  33. png.UpdatePipeline()
  34. def flush_render_buffer():
  35. '''When running as a single process use the WindowToImage filter to
  36. force a framebuffer read. This bypasses driver optimizations that
  37. perform lazy rendering and allows you to get actual frame rates for
  38. a single process with a GPU. Multi-process doesn't need this since
  39. compositing forces the frame buffer read.
  40. '''
  41. # If we're not using off-screen rendering then we can bypass this since
  42. # the frame buffer display will force a GL flush
  43. w = GetRenderView().SMProxy.GetRenderWindow()
  44. if not w.GetOffScreenRendering():
  45. return
  46. from vtkmodules.vtkParallelCore import vtkMultiProcessController
  47. from vtkmodules.vtkRenderingCore import vtkWindowToImageFilter
  48. # If we're using MPI we can also bypass this since compositing will
  49. # for a GL flush
  50. controller = vtkMultiProcessController.GetGlobalController()
  51. if controller.GetNumberOfProcesses() > 1:
  52. return
  53. # Force a GL flush by retrieving the frame buffer image
  54. w2i = vtkWindowToImageFilter()
  55. w2i.ReadFrontBufferOff()
  56. w2i.ShouldRerenderOff()
  57. w2i.SetInput(w)
  58. w2i.Modified()
  59. w2i.Update()
  60. def memtime_stamp():
  61. global records
  62. global n0
  63. m = logbase.get_memuse()
  64. n1 = dt.datetime.now()
  65. et = n1 - n0
  66. print(et, m)
  67. n0 = n1
  68. records.append([et, m])
  69. def run(output_basename='log', dimension=100, view_size=(1920, 1080),
  70. num_frames=10, save_logs=True, ospray=False):
  71. from vtkmodules.vtkParallelCore import vtkMultiProcessController
  72. from vtkmodules.vtkCommonSystem import vtkTimerLog
  73. controller = vtkMultiProcessController.GetGlobalController()
  74. view = get_render_view(view_size)
  75. if ospray:
  76. view.EnableRayTracing = 1
  77. print('Generating wavelet')
  78. wavelet = Wavelet()
  79. d2 = dimension//2
  80. wavelet.WholeExtent = [-d2, d2, -d2, d2, -d2, d2]
  81. wavelet.Maximum = 100.0
  82. waveletDisplay = Show()
  83. waveletDisplay.SetRepresentationType('Volume')
  84. print('Repositioning initial camera')
  85. c = GetActiveCamera()
  86. c.Azimuth(22.5)
  87. c.Elevation(22.5)
  88. print('Rendering first frame')
  89. Render()
  90. print('Saving frame 0 screenshot')
  91. import math
  92. fdigits = int(math.ceil(math.log(num_frames, 10)))
  93. frame_fname_fmt = output_basename + '.scene.f%(f)0' + str(fdigits) + 'd.png'
  94. SaveScreenshot(frame_fname_fmt % {'f': 0})
  95. print('Gathering geometry counts')
  96. vtkTimerLog.MarkStartEvent('GetViewItemStats')
  97. num_voxels = 0
  98. for r in view.Representations:
  99. num_voxels += r.GetRepresentedDataInformation().GetNumberOfCells()
  100. vtkTimerLog.MarkEndEvent('GetViewItemStats')
  101. print('Beginning benchmark loop')
  102. deltaAz = 45.0 / num_frames
  103. deltaEl = 45.0 / num_frames
  104. memtime_stamp()
  105. fpsT0 = dt.datetime.now()
  106. for frame in range(1, num_frames):
  107. c.Azimuth(deltaAz)
  108. c.Elevation(deltaEl)
  109. Render()
  110. flush_render_buffer()
  111. memtime_stamp()
  112. fpsT1 = dt.datetime.now()
  113. if controller.GetLocalProcessId() == 0:
  114. if save_logs:
  115. # Save the arguments this was executed with
  116. with open(output_basename + '.args.txt', 'w') as argfile:
  117. argfile.write(str({
  118. 'output_basename': output_basename,
  119. 'dimension': dimension,
  120. 'view_size': view_size,
  121. 'num_frames': num_frames,
  122. 'ospray' : ospray,
  123. 'save_logs': save_logs}))
  124. # Save the memory statistics collected
  125. with open(output_basename + '.mem.txt', 'w') as ofile:
  126. ofile.write('\n'.join([str(x) for x in records]))
  127. # Process frame timing statistics
  128. logparser.summarize_results(num_frames, (fpsT1-fpsT0).total_seconds(),
  129. num_voxels, 'Voxels', save_logs,
  130. output_basename)
  131. def main(argv):
  132. import argparse
  133. parser = argparse.ArgumentParser(
  134. description='Benchmark ParaView geometry rendering')
  135. parser.add_argument('-o', '--output-basename', default='log', type=str,
  136. help='Basename to use for generated output files')
  137. parser.add_argument('-d', '--dimension', default=100, type=int,
  138. help='The dimension of each side of the cubic volume')
  139. parser.add_argument('-v', '--view-size', default=[400, 400],
  140. type=lambda s: [int(x) for x in s.split(',')],
  141. help='View size used to render')
  142. parser.add_argument('-f', '--frames', default=10, type=int,
  143. help='Number of frames')
  144. parser.add_argument('-y', '--ospray', action='store_true',
  145. help='Use OSPRAY to render')
  146. args = parser.parse_args(argv)
  147. options = servermanager.vtkRemotingCoreConfiguration.GetInstance()
  148. url = options.GetServerURL()
  149. if url:
  150. import re
  151. m = re.match('([^:/]*://)?([^:]*)(:([0-9]+))?', url)
  152. if m.group(4):
  153. Connect(m.group(2), m.group(4))
  154. else:
  155. Connect(m.group(2))
  156. run(output_basename=args.output_basename, dimension=args.dimension,
  157. view_size=args.view_size, num_frames=args.frames, ospray=args.ospray)
  158. if __name__ == "__main__":
  159. import sys
  160. main(sys.argv[1:])