HWsir
(Hwsir)
January 15, 2023, 8:47am
1
I am using wslink and remote rendering to display the results of 3D reconstruction of medical images and cut through boxwidget on the web page, but the web page only displays images. After that, I displayed an official case with boxwedgt on the web page, showing the peripheral border, but unable to operate, and python.exe exited abnormally. I want to know whether it is feasible to display images on the front-end web page and cut them through remote rendering, or is my project missing some key configurations?
Web page display
The effect I want
Forrest
(Forrest)
January 17, 2023, 2:30pm
2
Are you using trame, or some other way to achieve remote rendering? Do you get an error, or is it a silent exit?
And how did you setup your widget on the server side?
HWsir
(Hwsir)
January 18, 2023, 1:08am
4
I don’t seem to have this problem with trame implementation, but I do have this problem when I configure the vtk server separately and make use of remoteview,When I added the border and cutting function to the 3D image, there were two cases, one is the border does not show, the other is silent exit
HWsir
(Hwsir)
January 18, 2023, 1:15am
5
it is the python code
import os
# import vtk modules.
import vtk as vk
from vtk.web import protocols
from vtk.web import wslink as vtk_wslink
from wslink import server
import argparse
class _WebCone(vtk_wslink.ServerProtocol):
# Application configuration
view = None
authKey = "wslink-secret"
def initialize(self):
# Bring used componets
self.registerVtkWebProtocol(protocols.vtkWebMouseHandler())
self.registerVtkWebProtocol(protocols.vtkWebViewPort())
self.registerVtkWebProtocol(protocols.vtkWebPublishImageDelivery(decode=False))
self.registerVtkWebProtocol(protocols.vtkWebViewPortGeometryDelivery())
# Update authentication key to use
self.updateSecret(_WebCone.authKey)
# tell the C++ web app to use no encoding.
# ParaViewWebPublishImageDelivery must be set to decode=False to match.
self.getApplication().SetImageEncoding(0)
# Create default pipeline (Only once for all the session)
if not _WebCone.view:
class IPWCallback: # 回调函数
def __init__(self, plane, mapper):
self.plane = plane
self.mapper = mapper
def __call__(self, caller, ev):
rep = caller.GetRepresentation()
rep.GetPlanes(self.plane)
self.mapper.SetClippingPlanes(self.plane)
l_reader = vk.vtkDICOMImageReader()
l_reader.SetDirectoryName(
"C:/Users/users_evptg5m/Desktop/datadicoms/manifest-1661804494842/CMB-PCA/CMB-PCA-MSB-02917/09-24-1958-NA-CT CAP-33859/4.000000-BONE-43921")
l_renderer = vk.vtkRenderer()
l_renderer.SetBackground(0.3, 0.3, 0.3)
l_render_windows = vk.vtkRenderWindow()
l_render_windows.AddRenderer(l_renderer)
l_render_windows.SetSize(900, 900)
l_trackball = vk.vtkInteractorStyleTrackballCamera()
l_iren = vk.vtkRenderWindowInteractor()
l_iren.SetInteractorStyle(l_trackball)
l_iren.SetRenderWindow(l_render_windows)
l_iren.GetInteractorStyle().SetDefaultRenderer(l_renderer)
l_iren.SetDesiredUpdateRate(15)
l_render_windows.Render()
l_gpu_mapper = vk.vtkGPUVolumeRayCastMapper()
l_gpu_mapper.SetInputConnection(l_reader.GetOutputPort())
wl = 260.00
ww = 270.00
l_color = vk.vtkColorTransferFunction()
l_color.SetColorSpaceToRGB()
l_color.AddRGBPoint(wl - ww / 2, 0, 0, 0)
l_color.AddRGBPoint(wl - ww / 2 + 94 * (ww / 255.0), 1., 21. / 255.0, 27. / 255.0)
l_color.AddRGBPoint(wl - ww / 2 + 147 * (ww / 255.0), 1., 176. / 255.0, 9. / 255.0)
l_color.AddRGBPoint(wl - ww / 2 + 201 * (ww / 255.0), 1., 241. / 255.0, 39. / 255.0)
l_color.AddRGBPoint(wl - ww / 2 + 255 * (ww / 255.0), 1, 1, 1.)
l_color.Build()
l_opacity = vk.vtkPiecewiseFunction()
l_opacity.AddPoint(wl - ww / 2, 0)
l_opacity.AddPoint(wl + ww / 2, 1)
l_volume_property = vk.vtkVolumeProperty()
l_volume_property.SetColor(l_color)
l_volume_property.SetScalarOpacity(l_opacity)
l_volume_property.SetInterpolationTypeToLinear()
l_volume_property.ShadeOn()
l_volume_property.SetAmbient(0.15)
l_volume_property.SetDiffuse(0.8)
l_volume_property.SetSpecular(0.25)
l_volume_property.SetSpecularPower(40)
l_volume = vk.vtkVolume()
l_volume.SetProperty(l_volume_property)
l_volume.SetMapper(l_gpu_mapper)
l_renderer.AddVolume(l_volume)
l_renderer.ResetCamera()
l_box_rep = vk.vtkBoxRepresentation()
l_box_rep.SetInsideOut(True)
l_voi_widget = vk.vtkBoxWidget2()
l_voi_widget.SetRepresentation(l_box_rep)
l_voi_widget.SetInteractor(l_iren)
l_voi_widget.GetRepresentation().SetPlaceFactor(1.)
l_voi_widget.GetRepresentation().PlaceWidget(l_reader.GetOutput().GetBounds())
l_voi_widget.SetEnabled(True)
l_planes = vk.vtkPlanes()
my_callback = IPWCallback(l_planes, l_gpu_mapper)
l_voi_widget.AddObserver('InteractionEvent', my_callback)
# VTK Web application specific
_WebCone.view = l_render_windows
self.getApplication().GetObjectIdMap().SetActiveObject("VIEW", l_render_windows)
if __name__ == "__main__":
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)
it is the js code
import vtkWSLinkClient from '@kitware/vtk.js/IO/Core/WSLinkClient';
import SmartConnect from 'wslink/src/SmartConnect';
import vtkRemoteView from '@kitware/vtk.js/Rendering/Misc/RemoteView';
vtkWSLinkClient.setSmartConnectClass(SmartConnect);
document.body.style.padding = '0';
document.body.style.margin = '0';
const divRenderer = document.createElement('div');
document.body.appendChild(divRenderer);
divRenderer.style.position = 'relative';
divRenderer.style.width = '100vw';
divRenderer.style.height = '100vh';
divRenderer.style.overflow = 'hidden';
const clientToConnect = vtkWSLinkClient.newInstance();
// Error
clientToConnect.onConnectionError((httpReq) => {
const message =
(httpReq && httpReq.response && httpReq.response.error) ||
`Connection error`;
console.error(message);
console.log(httpReq);
});
// Close
clientToConnect.onConnectionClose((httpReq) => {
const message =
(httpReq && httpReq.response && httpReq.response.error) ||
`Connection close`;
console.error(message);
console.log(httpReq);
});
// hint: if you use the launcher.py and ws-proxy just leave out sessionURL
// (it will be provided by the launcher)
const config = {
application: 'cone',
sessionURL: 'ws://localhost:1234/ws',
};
// Connect
clientToConnect
.connect(config)
.then((validClient) => {
const viewStream = clientToConnect.getImageStream().createViewStream('-1');
const view = vtkRemoteView.newInstance({
rpcWheelEvent: 'viewport.mouse.zoom.wheel',
viewStream,
});
const session = validClient.getConnection().getSession();
view.setSession(session);
view.setContainer(divRenderer);
view.setInteractiveRatio(0.1); // the scaled image compared to the clients view resolution
view.setInteractiveQuality(50); // jpeg quality
window.addEventListener('resize', view.resize);
})
.catch((error) => {
console.error(error);
});
Maybe js lacks dependencies or the callback function is wrong?
Hello,
You can diagnose front-end issues with the web development features present in any of the major web browsers.
best,
Paulo
What about the working version in trame?
At first glance I don’t see anything wrong…
HWsir
(Hwsir)
January 21, 2023, 5:40am
8
thank you for your answer, I will try it.
1 Like
HWsir
(Hwsir)
January 21, 2023, 5:47am
9
Thank you, The above display does not use trame. And it’s normal for me to use trame. Now I’m ready to work with trame.
1 Like