1
0
mirror of https://github.com/paboyle/Grid.git synced 2025-04-25 05:05:56 +01:00
Grid/visualisation/FieldDensity.py
2025-04-24 13:47:34 -04:00

286 lines
9.3 KiB
Python

#!/usr/bin/env python
# noinspection PyUnresolvedReferences
import math
import vtk
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkCommonCore import (
VTK_VERSION_NUMBER,
vtkVersion
)
from vtkmodules.vtkCommonCore import VTK_DOUBLE
from vtkmodules.vtkCommonDataModel import vtkImageData
from vtkmodules.vtkFiltersCore import (
vtkMarchingCubes,
vtkStripper
)
from vtkmodules.vtkFiltersModeling import vtkOutlineFilter
from vtkmodules.vtkIOImage import (
vtkMetaImageReader,
vtkJPEGWriter,
vtkPNGWriter
)
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkCamera,
vtkPolyDataMapper,
vtkProperty,
vtkRenderWindow,
vtkRenderWindowInteractor,
vtkRenderer,
vtkWindowToImageFilter
)
class vtkTimerCallback():
def __init__(self, steps, imageData, iren):
self.timer_count = 0
self.steps = steps
self.imageData = imageData
self.iren = iren
self.timerId = None
self.step = 0
def execute(self, obj, event):
print(self.timer_count)
dims = self.imageData.GetDimensions()
t=self.step/10.0
z0 = 2
y0 = 4
x0 = 4
z1 = 14
y1 = 12
x1 = 12
for z in range(dims[2]):
for y in range(dims[1]):
for x in range(dims[0]):
self.imageData.SetScalarComponentFromDouble(x, y, z, 0,
math.sin(t)*math.exp(-0.25*((x-x0)*(x-x0)+(y-y0)*(y-y0)+(z-z0)*(z-z0)))
- math.cos(t)*math.exp(-0.25*((x-x1)*(x-x1)+(y-y1)*(y-y1)+(z-z1)*(z-z1))))
self.imageData.Modified()
iren = obj
iren.GetRenderWindow().Render()
self.timer_count += 1
self.step += 1
if self.step >= self.steps :
iren.DestroyTimer(self.timerId)
def WriteImage(fileName, renWin):
'''
'''
import os
if fileName:
# Select the writer to use.
path, ext = os.path.splitext(fileName)
ext = ext.lower()
if not ext:
ext = '.png'
fileName = fileName + ext
elif ext == '.jpg':
writer = vtkJPEGWriter()
else:
writer = vtkPNGWriter()
windowto_image_filter = vtkWindowToImageFilter()
windowto_image_filter.SetInput(renWin)
windowto_image_filter.SetScale(1) # image quality
windowto_image_filter.SetInputBufferTypeToRGBA()
writer.SetFileName(fileName)
writer.SetInputConnection(windowto_image_filter.GetOutputPort())
writer.Write()
else:
raise RuntimeError('Need a filename.')
def main():
colors = vtkNamedColors()
file_name = get_program_parameters()
colors.SetColor('InstantonColor', [240, 184, 160, 255])
colors.SetColor('BackfaceColor', [255, 229, 200, 255])
colors.SetColor('BkgColor', [51, 77, 102, 255])
# Create the renderer, the render window, and the interactor. The renderer
# draws into the render window, the interactor enables mouse- and
# keyboard-based interaction with the data within the render window.
#
a_renderer = vtkRenderer()
ren_win = vtkRenderWindow()
ren_win.AddRenderer(a_renderer)
iren = vtkRenderWindowInteractor()
iren.SetRenderWindow(ren_win)
# The following reader is used to read a series of 2D slices (images)
# that compose the volume. The slice dimensions are set, and the
# pixel spacing. The data Endianness must also be specified. The reader
# uses the FilePrefix in combination with the slice number to construct
# filenames using the format FilePrefix.%d. (In this case the FilePrefix
# is the root name of the file: quarter.)
imageData = vtkImageData()
imageData.SetDimensions(16, 16, 16)
imageData.AllocateScalars(VTK_DOUBLE, 1)
dims = imageData.GetDimensions()
# Fill every entry of the image data with '2.0'
# Set the input data
for z in range(dims[2]):
z0 = dims[2]/2
for y in range(dims[1]):
y0 = dims[1]/2
for x in range(dims[0]):
x0 = dims[0]/2
imageData.SetScalarComponentFromDouble(x, y, z, 0, math.exp(-0.25*((x-x0)*(x-x0)+(y-y0)*(y-y0)+z*z)) - math.exp(-0.25*((x-x0)*(x-x0)+y*y+(z-z0)*(z-z0))))
instanton_extractor = vtkMarchingCubes()
instanton_extractor.SetInputData(imageData)
instanton_extractor.SetValue(0, 0.1)
instanton_stripper = vtkStripper()
instanton_stripper.SetInputConnection(instanton_extractor.GetOutputPort())
instanton_mapper = vtkPolyDataMapper()
instanton_mapper.SetInputConnection(instanton_stripper.GetOutputPort())
instanton_mapper.ScalarVisibilityOff()
instanton = vtkActor()
instanton.SetMapper(instanton_mapper)
instanton.GetProperty().SetDiffuseColor(colors.GetColor3d('InstantonColor'))
instanton.GetProperty().SetSpecular(0.3)
instanton.GetProperty().SetSpecularPower(20)
instanton.GetProperty().SetOpacity(0.5)
# The triangle stripper is used to create triangle strips from the
# isosurface these render much faster on may systems.
antiinstanton_extractor = vtkMarchingCubes()
antiinstanton_extractor.SetInputData(imageData)
antiinstanton_extractor.SetValue(0, -0.1)
antiinstanton_stripper = vtkStripper()
antiinstanton_stripper.SetInputConnection(antiinstanton_extractor.GetOutputPort())
antiinstanton_mapper = vtkPolyDataMapper()
antiinstanton_mapper.SetInputConnection(antiinstanton_stripper.GetOutputPort())
antiinstanton_mapper.ScalarVisibilityOff()
antiinstanton = vtkActor()
antiinstanton.SetMapper(antiinstanton_mapper)
antiinstanton.GetProperty().SetDiffuseColor(colors.GetColor3d('Ivory'))
# An outline provides box around the data.
outline_data = vtkOutlineFilter()
outline_data.SetInputData(imageData)
map_outline = vtkPolyDataMapper()
map_outline.SetInputConnection(outline_data.GetOutputPort())
outline = vtkActor()
outline.SetMapper(map_outline)
outline.GetProperty().SetColor(colors.GetColor3d('Black'))
# It is convenient to create an initial view of the data. The FocalPoint
# and Position form a vector direction. Later on (ResetCamera() method)
# this vector is used to position the camera to look at the data in
# this direction.
a_camera = vtkCamera()
a_camera.SetViewUp(0, 0, -1)
a_camera.SetPosition(0, -100, 0)
a_camera.SetFocalPoint(0, 0, 0)
a_camera.ComputeViewPlaneNormal()
a_camera.Azimuth(30.0)
a_camera.Elevation(30.0)
# Actors are added to the renderer. An initial camera view is created.
# The Dolly() method moves the camera towards the FocalPoint,
# thereby enlarging the image.
a_renderer.AddActor(outline)
a_renderer.AddActor(instanton)
a_renderer.AddActor(antiinstanton)
a_renderer.SetActiveCamera(a_camera)
a_renderer.ResetCamera()
a_camera.Dolly(1.0)
# Set a background color for the renderer and set the size of the
# render window (expressed in pixels).
a_renderer.SetBackground(colors.GetColor3d('BkgColor'))
ren_win.SetSize(1024, 1024)
ren_win.SetWindowName('ExpoDemo')
# Note that when camera movement occurs (as it does in the Dolly()
# method), the clipping planes often need adjusting. Clipping planes
# consist of two planes: near and far along the view direction. The
# near plane clips out objects in front of the plane the far plane
# clips out objects behind the plane. This way only what is drawn
# between the planes is actually rendered.
a_renderer.ResetCameraClippingRange()
# write image
# WriteImage('exp.jpg',ren_win)
# Sign up to receive TimerEvent
cb = vtkTimerCallback(200, imageData, iren)
iren.AddObserver('TimerEvent', cb.execute)
cb.timerId = iren.CreateRepeatingTimer(50)
# start the interaction and timer
ren_win.Render()
# Initialize the event loop and then start it.
iren.Initialize()
iren.Start()
def get_program_parameters():
import argparse
description = 'Simple lattice volumetric demo'
epilogue = '''
Derived from VTK/Examples/Cxx/Medical2.cxx
'''
parser = argparse.ArgumentParser(description=description, epilog=epilogue,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('filename', help='FieldDensity.py')
args = parser.parse_args()
return args.filename
def vtk_version_ok(major, minor, build):
"""
Check the VTK version.
:param major: Major version.
:param minor: Minor version.
:param build: Build version.
:return: True if the requested VTK version is greater or equal to the actual VTK version.
"""
needed_version = 10000000000 * int(major) + 100000000 * int(minor) + int(build)
try:
vtk_version_number = VTK_VERSION_NUMBER
except AttributeError: # as error:
ver = vtkVersion()
vtk_version_number = 10000000000 * ver.GetVTKMajorVersion() + 100000000 * ver.GetVTKMinorVersion() \
+ ver.GetVTKBuildVersion()
if vtk_version_number >= needed_version:
return True
else:
return False
if __name__ == '__main__':
main()