[vtkusers] Python Remote Rendering Issues when Updating Model

Turner, Shruti s.turner17 at imperial.ac.uk
Mon Mar 18 12:56:50 EDT 2019


Hi all,

I am trying to get vtk remote rendering working for a web application and I feel like I’m almost there, but missing something minor.

When running my remote rendering code, I can see my model updating and it works perfectly on the view of the server side model.  However, vtk never opens the web socket link and I am, therefore, unable to view this in a browser window.  It appears to be a result of the vtk callback function which is used to update the model, but I’m not sure how to solve this problem.

Any pointers would be greatly appreciated!

Thanks,
Shruti

Here is my server side code:

vtk_server.py

# import to process args
import sys
import os

# import maths modules
import numpy as np
from scipy.interpolate import interp1d
from scipy import interpolate
from scipy import ndimage
from ReadCSV import readcsv
# from Interpolation import *

# import vtk modules.
import vtk
from vtk.web import protocols
from vtk.web import wslink as vtk_wslink
from wslink import server

from vtkTimerCallback import vtkTimerCallback

# import utility modules
import csv
import time

import argparse

# =============================================================================
# Create custom ServerProtocol class to handle clients requests
# =============================================================================

class _WebCone(vtk_wslink.ServerProtocol):
# Application configuration
view = None
authKey = "wslink-secret"

sensor_locations = [21035, 20577, 19625, 19121, 18110, 17567, 16501, 16495, 15942, 15347, 15314, 14658, 20506, 20027, 19544, 19044, 18546, 18031, 16957, 16416, 15851, 14574, 13733, 3424, 20501, 19525, 19025, 18527, 18013, 17488, 16962, 16427, 15233, 14578, 13746, 21726, 19982, 18981, 18478, 17427, 16902, 16361, 15793, 15188, 14536, 13691, 3370, 4899, 19446, 18434, 17382, 16856, 16310, 15122, 14465, 13599, 13609, 3291, 4957, 67, 19904, 19910, 18905, 18393, 17877, 17353, 16816, 15694, 15078, 14423, 13547, 3188, 19856, 19363, 18864, 17826, 17297, 17304, 16763, 16218, 15645, 15036, 13503, 3106, 19811, 18812, 18816, 17780, 17249, 16714, 16169, 15595, 14974, 14314, 13405, 21809, 19780, 19282, 18260, 17742, 16671, 15547, 14924, 14254, 2786, 2128, 975, 364, 19732, 18732, 18214, 17161, 16617, 16069, 14873, 13299, 2749, 925, 320, 866, 20624, 20151, 19660, 18656, 17626, 16571, 16015, 15436, 14153, 13250, 2675, 2009, 20658, 20162, 19178, 18174, 17650, 16577, 15458, 14822, 13236, 2678, 2652, 2634]

sensor_pressures = readcsv("S003_norm_walk.csv")
min_pressure = 0 # Standard scale - min pressure reading
max_pressure = 1 # Standard scale - max pressure reading
stl_filename = "newpivot.stl"

visualisationIndex = 0
allPressures = []

def initialize(self):
global renderer, renderWindow, renderWindowInteractor, cone, mapper, actor

# Bring used components
self.registerVtkWebProtocol(protocols.vtkWebMouseHandler())
self.registerVtkWebProtocol(protocols.vtkWebViewPort())
self.registerVtkWebProtocol(protocols.vtkWebViewPortImageDelivery())
self.registerVtkWebProtocol(protocols.vtkWebViewPortGeometryDelivery())

# Update authentication key to use
self.updateSecret(_WebCone.authKey)

# Create default pipeline (Only once for all the session)
if not _WebCone.view:
# VTK specific code
reader = vtk.vtkSTLReader()
reader.SetFileName(_WebCone.stl_filename)
reader.Update() # This is necessary to have the data ready to read.

obj = reader.GetOutputDataObject(0)

lut = vtk.vtkLookupTable()
lut.SetTableRange(_WebCone.min_pressure, _WebCone.max_pressure)
lut.SetHueRange(0.0, 0.9)
lut.SetSaturationRange(0.5, 1)
lut.SetValueRange(0.7, 1)
lut.Build()
renderer = vtk.vtkRenderer()
renderer.SetBackground(.1, .2, .4)
renderWindow = vtk.vtkRenderWindow()
renderWindow.AddRenderer(renderer)

renderWindowInteractor = vtk.vtkRenderWindowInteractor()
renderWindowInteractor.SetRenderWindow(renderWindow)
renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera()

obj = _WebCone.interpolate(self, obj)

mapper = vtk.vtkPolyDataMapper()
mapper.SetInputDataObject(obj)
mapper.SetScalarRange(_WebCone.min_pressure, _WebCone.max_pressure)
mapper.SetLookupTable(lut)

actor = vtk.vtkActor()
actor.SetMapper(mapper)

# create the scalar_bar
scalar_bar = vtk.vtkScalarBarActor()
scalar_bar.SetOrientationToHorizontal()
scalar_bar.SetLookupTable(lut)
scalar_bar.SetTitle("Scale")
scalar_bar.SetNumberOfLabels(8)
scalar_bar.GetTitleTextProperty().SetFontSize(15)
scalar_bar.GetLabelTextProperty().SetFontSize(10)

# create the scalar_bar_widget
scalar_bar_widget = vtk.vtkScalarBarWidget()
scalar_bar_widget.SetInteractor(renderWindowInteractor)
scalar_bar_widget.SetScalarBarActor(scalar_bar)
scalar_bar_widget.On()

renderer.AddActor(actor)
renderer.ResetCamera()
renderWindow.Render()
# CALL BACK STUFF
cb = vtkTimerCallback(self.sensor_pressures, self.sensor_locations, obj, self.allPressures, self.visualisationIndex, obj.GetNumberOfPoints())
cb.actor = actor
renderWindowInteractor.AddObserver('TimerEvent', cb.execute)
timerID = renderWindowInteractor.CreateRepeatingTimer(20)

renderWindowInteractor.Start()

# VTK Web application specific
_WebCone.view = renderWindowInteractor
self.getApplication().GetObjectIdMap().SetActiveObject("VIEW", renderWindowInteractor)


def interpolate(self, obj):
filename = "Points with coordinates.csv"
file = open(filename, "r")
reader = csv.reader(file, delimiter=";")

rownum = 0
values = []

for row in reader:
if rownum == 0:
rownum += 1
else:
strrow = row
new = strrow[0].split(',')
values.append(new)
rownum += 1
file.close()

xi = []
yi = []
zi = []

for value in values:
xi.append(value[1])
yi.append(value[2])
zi.append(value[3])

xfixed = []
yfixed = []
zfixed = []
for value in xi:
xfixed.append(float(value))
for value in yi:
yfixed.append(float(value))
for value in zi:
zfixed.append(float(value))

xpressures = []
ypressures = []
zpressures = []
for sensor in _WebCone.sensor_locations:
xpressures.append(xfixed[sensor])
ypressures.append(yfixed[sensor])
zpressures.append(zfixed[sensor])

if len(_WebCone.allPressures) == 0:
file = open("S003_norm_walk.csv", 'r')
reader = csv.reader(file, delimiter=';')
for row in reader:
_WebCone.allPressures.append(row)
file.close()

values = []
new = _WebCone.allPressures[_WebCone.visualisationIndex][0].split(',')
values.append(new)
pressures_new = values[0]
pressures = []
for item in pressures_new[1:145]:
pressures.append(float(item))

vertex_pressures = np.zeros(obj.GetNumberOfPoints())

xpressures= np.array(xpressures)
ypressures= np.array(ypressures)
zpressures= np.array(zpressures)
xfixed =np.array(xfixed)
yfixed = np.array(yfixed)
zfixed = np.array(zfixed)
pressures = np.array(pressures)
# RBF shiv interpolation
f = interpolate.Rbf(xpressures,ypressures,zpressures,pressures,function='cubic')
vertex_pressures = f(xfixed,yfixed,zfixed)

pressures = vtk.vtkDoubleArray()
pressures.SetName("Pressures")

# Loop through the points in the vtkPolyData and record the height in the
# 'heights' array.
for i in range(obj.GetNumberOfPoints()):
p = vertex_pressures[i]
pressures.InsertNextValue(p)

# Add this array to the point data as a scalar.
obj.GetPointData().SetScalars(pressures)

return obj


# =============================================================================
# Main: Parse args and start server
# =============================================================================

if __name__ == "__main__":
# Create argument parser
parser = argparse.ArgumentParser(description="VTK/Web Cone web-application")

# Add default arguments
server.add_arguments(parser)

# Extract arguments
args = parser.parse_args()

# Configure our current application
_WebCone.authKey = args.authKey

# Start server
server.start_webserver(options=args, protocol=_WebCone)





vtktimercallback.py


# import to process args
import sys
import os

# import maths modules
import numpy as np
from scipy.interpolate import interp1d
from scipy import interpolate
from scipy import ndimage
from ReadCSV import readcsv
# from Interpolation import *

# import vtk modules.
import vtk
from vtk.web import protocols
from vtk.web import wslink as vtk_wslink
from wslink import server


# import utility modules
import csv
import time


class vtkTimerCallback():
def __init__(self, sensors_values, sensor_locations, obj, all_pressures, visualisationIndex, number_of_points):
self.timer_count = 0
self.changed = False
self.sensors_values = sensors_values
self.sensor_locations = sensor_locations
self.obj = obj
self.all_pressures = all_pressures
self.visualisationIndex = visualisationIndex
self.number_of_points = number_of_points

def execute(self, obj, x):
self.changed = False

filename = "Points with coordinates.csv"
file = open(filename, "r")
reader = csv.reader(file, delimiter=";")

rownum = 0
values = []

for row in reader:
if rownum == 0:
rownum += 1
else:
strrow = row
new = strrow[0].split(',')
values.append(new)
rownum += 1
file.close()
if (self.timer_count + 500) < rownum:

xi = []
yi = []
zi = []

for value in values:
xi.append(value[1])
yi.append(value[2])
zi.append(value[3])

xfixed = []
yfixed = []
zfixed = []
for value in xi:
xfixed.append(float(value))
for value in yi:
yfixed.append(float(value))
for value in zi:
zfixed.append(float(value))

xpressures = []
ypressures = []
zpressures = []
for sensor in self.sensor_locations:
xpressures.append(xfixed[sensor])
ypressures.append(yfixed[sensor])
zpressures.append(zfixed[sensor])

if len(self.all_pressures) == 0:
file = open("S003_norm_walk.csv", 'r')
reader = csv.reader(file, delimiter=';')
for row in reader:
self.all_pressures.append(row)
file.close()

values = []
new = self.all_pressures[self.timer_count][0].split(',')
values.append(new)
pressures_new = values[0]
pressures = []
for item in pressures_new[1:145]:
pressures.append(float(item))

# Build vertex_pressures via interpolation
#GetNumberOfPoints gets the points that VTK has assigned to the map
#array of vz-vy-vz triplets
#what does line 45 return....
vertex_pressures = np.zeros(self.number_of_points)

# for i in range(0, len(sensor_locations)):
# p = pressures[i]
# vertex_pressures[sensor_locations[i]] = pressures[i]
# coord = np.array((xpressures,ypressures)).T
# newcoord = np.array((xfixed,yfixed)).T
xpressures= np.array(xpressures)
ypressures= np.array(ypressures)
zpressures= np.array(zpressures)
xfixed =np.array(xfixed)
yfixed = np.array(yfixed)
zfixed = np.array(zfixed)
pressures = np.array(pressures)
# RBF shiv interpolation
f = interpolate.Rbf(xpressures,ypressures,zpressures,pressures,function='cubic')
vertex_pressures = f(xfixed,yfixed,zfixed)

# This is an array that I am creating to store the heights of the points. I
# will use this as a scalar field on the 'obj' so that the lookup table can be
# used to color it. You could obviously make the array anything you wanted,
# such as x or y or squared distance from some other point, for instance.
pressures = vtk.vtkDoubleArray()
pressures.SetName("Pressures")

# Loop through the points in the vtkPolyData and record the height in the
# 'heights' array.
for i in range(self.number_of_points):
p = vertex_pressures[i]
pressures.InsertNextValue(p)

# Add this array to the point data as a scalar.
self.obj.GetPointData().SetScalars(pressures)

# Visualization stuff ... you need to tell the mapper about the scalar field
# and the lookup table. The rest of this is pretty standard stuff.
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputDataObject(self.obj)

iren = obj
iren.GetRenderWindow().Render()
self.timer_count += 500
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://vtk.org/pipermail/vtkusers/attachments/20190318/59e3f7e2/attachment.html>


More information about the vtkusers mailing list