Skip to content

Commit 7dc827f

Browse files
add vtk_protocols
1 parent 1cb965b commit 7dc827f

File tree

2 files changed

+191
-2
lines changed

2 files changed

+191
-2
lines changed

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
55

66
[project]
77
name = "OpenGeodeWeb-Viewer"
8-
version = "0.0.1"
8+
version = "0.0.2"
99
authors = [
1010
{ name="Geode-solutions", email="[email protected]" },
1111
]
@@ -20,7 +20,6 @@ classifiers = [
2020
dependencies = [
2121
"wslink[ssl]",
2222
"numpy",
23-
"vtk"
2423
]
2524

2625
[project.urls]
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
from vtk.web import protocols as vtk_protocols
2+
from wslink import register as exportRpc
3+
4+
import vtk
5+
6+
7+
class VtkView(vtk_protocols.vtkWebProtocol):
8+
def __init__(self):
9+
self.DataReader = vtk.vtkXMLPolyDataReader()
10+
self.ImageReader = vtk.vtkXMLImageDataReader()
11+
12+
@exportRpc("create_visualization")
13+
def create_visualization(self):
14+
renderWindow = self.getView("-1")
15+
renderer = renderWindow.GetRenderers().GetFirstRenderer()
16+
renderer.SetBackground([180 / 255, 180 / 255, 180 / 255])
17+
18+
renderer.ResetCamera()
19+
renderWindow.Render()
20+
21+
return self.reset_camera()
22+
23+
@exportRpc("reset_camera")
24+
def reset_camera(self):
25+
renderWindow = self.getView("-1")
26+
renderWindow.GetRenderers().GetFirstRenderer().ResetCamera()
27+
renderWindow.Render()
28+
29+
return -1
30+
31+
@exportRpc("create_object_pipeline")
32+
def create_object_pipeline(self, params):
33+
try:
34+
print(f"{params=}", flush=True)
35+
id = params["id"]
36+
file_name = params["file_name"]
37+
38+
actor = vtk.vtkActor()
39+
mapper = vtk.vtkDataSetMapper()
40+
actor.SetMapper(mapper)
41+
if ".vtm" in file_name:
42+
reader = vtk.vtkXMLMultiBlockDataReader()
43+
filter = vtk.vtkCompositeDataGeometryFilter()
44+
filter.SetInputConnection(reader.GetOutputPort())
45+
mapper.SetInputConnection(filter.GetOutputPort())
46+
self.register_object(id, reader, filter, actor, mapper, {})
47+
else:
48+
reader = vtk.vtkXMLGenericDataObjectReader()
49+
mapper.SetInputConnection(reader.GetOutputPort())
50+
self.register_object(id, reader, {}, actor, mapper, {})
51+
52+
reader.SetFileName(f"/data/{file_name}")
53+
54+
mapper.SetColorModeToMapScalars()
55+
mapper.SetResolveCoincidentTopologyLineOffsetParameters(1, -0.1)
56+
mapper.SetResolveCoincidentTopologyPolygonOffsetParameters(2, 0)
57+
mapper.SetResolveCoincidentTopologyPointOffsetParameter(-2)
58+
59+
renderWindow = self.getView("-1")
60+
renderer = renderWindow.GetRenderers().GetFirstRenderer()
61+
renderer.AddActor(actor)
62+
63+
renderer.ResetCamera()
64+
65+
self.render()
66+
except Exception as e:
67+
print("error : ", str(e), flush=True)
68+
69+
@exportRpc("toggle_object_visibility")
70+
def toggle_object_visibility(self, params):
71+
print(f"{params=}", flush=True)
72+
id = params["id"]
73+
is_visible = params["is_visible"]
74+
object = self.get_object(id)
75+
actor = object["actor"]
76+
actor.SetVisibility(is_visible)
77+
self.render()
78+
79+
@exportRpc("apply_textures")
80+
def apply_textures(self, params):
81+
print(f"{params=}", flush=True)
82+
id = params["id"]
83+
textures = params["textures"]
84+
textures_array = []
85+
images_reader_array = []
86+
87+
data = self.get_object(id)
88+
mapper = data["mapper"]
89+
actor = data["actor"]
90+
reader = data["reader"]
91+
92+
polydata_mapper = mapper.GetPolyDataMapper()
93+
poly_data = reader.GetPolyDataOutput()
94+
95+
for index, value in enumerate(textures):
96+
texture_name = value["texture_name"]["value"]
97+
texture_file_name = value["texture_file_name"]["value"]
98+
99+
new_texture = vtk.vtkTexture()
100+
image_reader = vtk.vtkXMLImageDataReader()
101+
image_reader.SetFileName(f"/data/{texture_file_name}")
102+
103+
shader_texture_name = f"VTK_TEXTURE_UNIT_{index}"
104+
polydata_mapper.MapDataArrayToMultiTextureAttribute(
105+
shader_texture_name,
106+
texture_name,
107+
vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS,
108+
)
109+
110+
if index == 0:
111+
new_texture.SetBlendingMode(
112+
vtk.vtkTexture.VTK_TEXTURE_BLENDING_MODE_REPLACE
113+
)
114+
else:
115+
new_texture.SetBlendingMode(
116+
vtk.vtkTexture.VTK_TEXTURE_BLENDING_MODE_ADD
117+
)
118+
119+
images_reader_array.append(image_reader)
120+
new_texture.SetInputConnection(image_reader.GetOutputPort())
121+
122+
actor.GetProperty().SetTexture(shader_texture_name, new_texture)
123+
124+
textures_array.append(new_texture)
125+
images_reader_array.append(image_reader)
126+
127+
self.render()
128+
129+
@exportRpc("update_data")
130+
def update_data(self, params):
131+
print(f"{params=}", flush=True)
132+
id = params["id"]
133+
134+
data = self.get_object(id)
135+
reader = data["reader"]
136+
reader.Modified()
137+
138+
self.render()
139+
140+
@exportRpc("get_point_position")
141+
def get_point_position(self, params):
142+
x = float(params["x"])
143+
y = float(params["y"])
144+
print(f"{x=}", flush=True)
145+
print(f"{y=}", flush=True)
146+
xyz = [x, y, 0.0]
147+
picker = vtk.vtkWorldPointPicker()
148+
picker.Pick(xyz, self.get_renderer())
149+
ppos = picker.GetPickPosition()
150+
return {"x": ppos[0], "y": ppos[1], "z": ppos[2]}
151+
152+
@exportRpc("reset")
153+
def reset(self):
154+
renderWindow = self.getView("-1")
155+
renderWindow.GetRenderers().GetFirstRenderer().RemoveAllViewProps()
156+
print("reset")
157+
158+
def getProtocol(self, name):
159+
for p in self.coreServer.getLinkProtocols():
160+
if type(p).__name__ == name:
161+
return p
162+
163+
def render(self, view=-1):
164+
self.getProtocol("vtkWebPublishImageDelivery").imagePush({"view": view})
165+
166+
def get_data_base(self):
167+
return self.getSharedObject("db")
168+
169+
def get_renderer(self):
170+
return self.getSharedObject("renderer")
171+
172+
def get_object(self, id):
173+
return self.get_data_base()[id]
174+
175+
def get_protocol(self, name):
176+
for p in self.coreServer.getLinkProtocols():
177+
if type(p).__name__ == name:
178+
return p
179+
180+
def render(self, view=-1):
181+
self.getProtocol("vtkWebPublishImageDelivery").imagePush({"view": view})
182+
183+
def register_object(self, id, reader, filter, actor, mapper, textures):
184+
self.get_data_base()[id] = {
185+
"reader": reader,
186+
"filter": filter,
187+
"actor": actor,
188+
"mapper": mapper,
189+
"textures": textures,
190+
}

0 commit comments

Comments
 (0)