Skip to content

Commit 4ebce40

Browse files
Merge branch 'next' of https://github.com/Geode-solutions/OpenGeodeWeb-Viewer into feat/mesh_sub_protocols
2 parents 1e4a3e8 + 4709c1b commit 4ebce40

File tree

5 files changed

+186
-33
lines changed

5 files changed

+186
-33
lines changed

CHANGELOG.md

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
# CHANGELOG
22

33

4+
## v1.1.0 (2024-12-09)
5+
6+
7+
## v1.1.0-rc.2 (2024-12-09)
8+
9+
### Bug Fixes
10+
11+
- **edit schema**: Rv schema step
12+
([`7162f00`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/7162f00bdba04d29a84e80d16074dc59d64c6c73))
13+
14+
15+
## v1.1.0-rc.1 (2024-12-04)
16+
17+
418
## v1.0.0 (2024-11-29)
519

620

@@ -35,16 +49,23 @@
3549

3650
### Features
3751

52+
- **generic rpcs**: Refactor all classes/tests
53+
([`563f41b`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/563f41bc0741ab1dae9e5df9244e545e6ba47993))
54+
55+
- **generic rpcs**: Refactor all classes/tests
56+
([`297b005`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/297b0050e4ab47817659021c3a099e715fba6a87))
57+
58+
- **get_mouse**: New rpc
59+
([`94280f3`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/94280f3bc30f03e0c550cd7baf76afd30192c1e3))
60+
3861
- **new rpcs**: Refactor rpcs
3962
([`c2fb4e7`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/c2fb4e75b83a862267ed4641e41e9344e6a2d70f))
4063

4164
BREAKING CHANGE: change some rpc names in schemas
4265

43-
- **generic rpcs**: Refactor all classes/tests
44-
([`563f41b`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/563f41bc0741ab1dae9e5df9244e545e6ba47993))
66+
### BREAKING CHANGES
4567

46-
- **generic rpcs**: Refactor all classes/tests
47-
([`297b005`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/297b0050e4ab47817659021c3a099e715fba6a87))
68+
- **new rpcs**: Change some rpc names in schemas
4869

4970

5071
## v0.4.0-rc.1 (2024-11-25)
@@ -152,32 +173,32 @@ BREAKING CHANGE: change some rpc names in schemas
152173

153174
### Bug Fixes
154175

155-
- **schemas**: Delete image docker
156-
([`ebd416b`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/ebd416b5eceaecfce61d3c5e136cc3d6ed36184b))
157-
158176
- **license**: Add copyleft file
159177
([`a0cfd33`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/a0cfd3335e0b12913947917b631b5e13889a9107))
160178

179+
- **schemas**: Delete image docker
180+
([`ebd416b`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/ebd416b5eceaecfce61d3c5e136cc3d6ed36184b))
181+
161182
### Chores
162183

163184
- **licence**: Happy new year 2024
164185
([`a69cefe`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/a69cefe053e43a170db48ea31bbc3619feb49bc6))
165186

166187
### Features
167188

189+
- **delete_object_pipeline**: Add rpc
190+
([`5a4df6a`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/5a4df6a5d20451491fe27d89886459d9a38f78cd))
191+
192+
Enables an object to be deleted from the viewer
193+
168194
- **schemas**: Remove dockerfile + a few changes
169195
([`e81296a`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/e81296af2510c975c1d98034f269a5c94e4b89f5))
170196

171-
- **schemas**: Test2
172-
([`53dfa45`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/53dfa45953b098f8ecda5d8773e37fe064b4e7e3))
173-
174197
- **schemas**: Test
175198
([`6088534`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/6088534e990f44559575f2d4631bc731210e2243))
176199

200+
- **schemas**: Test2
201+
([`53dfa45`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/53dfa45953b098f8ecda5d8773e37fe064b4e7e3))
202+
177203
- **unit tests**: Run server
178204
([`11291b8`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/11291b8e808e52e1f4e6d0ab11b739ffd1542ecb))
179-
180-
- **delete_object_pipeline**: Add rpc
181-
([`5a4df6a`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/5a4df6a5d20451491fe27d89886459d9a38f78cd))
182-
183-
Enables an object to be deleted from the viewer

pyproject.toml

Lines changed: 1 addition & 1 deletion
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 = "1.0.0"
8+
version = "1.1.0"
99
dynamic = ["dependencies"]
1010
authors = [
1111
{ name="Geode-solutions", email="[email protected]" },
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"rpc": "picked_ids",
3+
"type": "object",
4+
"properties": {
5+
"x": {
6+
"type": "number"
7+
},
8+
"y": {
9+
"type": "number"
10+
},
11+
"ids": {
12+
"type": "array",
13+
"items": {
14+
"type": "string"
15+
}
16+
}
17+
},
18+
"required": [
19+
"x",
20+
"y",
21+
"ids"
22+
],
23+
"additionalProperties": false
24+
}

src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Standard library imports
2+
import math
23
import os
34

45
# Third party imports
@@ -11,6 +12,7 @@
1112
from opengeodeweb_viewer.utils_functions import get_schemas_dict, validate_schema
1213
from opengeodeweb_viewer.vtk_protocol import VtkView
1314

15+
1416
class VtkViewerView(VtkView):
1517
prefix = "opengeodeweb_viewer.viewer."
1618
schemas_dict = get_schemas_dict(os.path.join(os.path.dirname(__file__), "schemas"))
@@ -20,7 +22,9 @@ def __init__(self):
2022

2123
@exportRpc(prefix + schemas_dict["create_visualization"]["rpc"])
2224
def createVisualization(self, params):
23-
print(self.schemas_dict["create_visualization"]["rpc"], f"{params=}", flush=True)
25+
print(
26+
self.schemas_dict["create_visualization"]["rpc"], f"{params=}", flush=True
27+
)
2428
validate_schema(params, self.schemas_dict["create_visualization"])
2529
renderWindow = self.getView("-1")
2630
renderer = renderWindow.GetRenderers().GetFirstRenderer()
@@ -31,7 +35,9 @@ def createVisualization(self, params):
3135

3236
@exportRpc(prefix + schemas_dict["set_background_color"]["rpc"])
3337
def setBackgroundColor(self, params):
34-
print(self.schemas_dict["set_background_color"]["rpc"], f"{params=}", flush=True)
38+
print(
39+
self.schemas_dict["set_background_color"]["rpc"], f"{params=}", flush=True
40+
)
3541
validate_schema(params, self.schemas_dict["set_background_color"])
3642
renderWindow = self.getView("-1")
3743
renderer = renderWindow.GetRenderers().GetFirstRenderer()
@@ -87,7 +93,7 @@ def takeScreenshot(self, params):
8793
else:
8894
raise Exception("output_extension not supported")
8995

90-
new_filename = filename + '.' + output_extension
96+
new_filename = filename + "." + output_extension
9197
file_path = os.path.join(self.DATA_FOLDER_PATH, new_filename)
9298
writer.SetFileName(file_path)
9399
writer.SetInputConnection(w2if.GetOutputPort())
@@ -98,7 +104,6 @@ def takeScreenshot(self, params):
98104

99105
return {"blob": self.addAttachment(file_content)}
100106

101-
102107
@exportRpc(prefix + schemas_dict["update_data"]["rpc"])
103108
def updateData(self, params):
104109
print(self.schemas_dict["update_data"]["rpc"], f"{params=}", flush=True)
@@ -139,3 +144,44 @@ def reset(self, params):
139144
validate_schema(params, self.schemas_dict["reset"])
140145
renderWindow = self.getView("-1")
141146
renderWindow.GetRenderers().GetFirstRenderer().RemoveAllViewProps()
147+
148+
def computeEpsilon(self, renderer, z):
149+
renderer.SetDisplayPoint(0, 0, z)
150+
renderer.DisplayToWorld()
151+
windowLowerLeft = renderer.GetWorldPoint()
152+
size = renderer.GetRenderWindow().GetSize()
153+
renderer.SetDisplayPoint(size[0], size[1], z)
154+
renderer.DisplayToWorld()
155+
windowUpperRight = renderer.GetWorldPoint()
156+
epsilon = 0
157+
for i in range(3):
158+
epsilon += (windowUpperRight[i] - windowLowerLeft[i]) * (
159+
windowUpperRight[i] - windowLowerLeft[i]
160+
)
161+
return math.sqrt(epsilon) * 0.0125
162+
163+
@exportRpc(prefix + schemas_dict["picked_ids"]["rpc"])
164+
def pickedIds(self, params):
165+
print(self.schemas_dict["picked_ids"]["rpc"], f"{params=}", flush=True)
166+
validate_schema(params, self.schemas_dict["picked_ids"])
167+
x = params["x"]
168+
y = params["y"]
169+
ids = params["ids"]
170+
171+
renderWindow = self.getView("-1")
172+
renderer = renderWindow.GetRenderers().GetFirstRenderer()
173+
picker = vtk.vtkWorldPointPicker()
174+
picker.Pick([x, y, 0], renderer)
175+
point = picker.GetPickPosition()
176+
epsilon = self.computeEpsilon(renderer, point[2])
177+
bbox = vtk.vtkBoundingBox()
178+
bbox.AddPoint(point[0] + epsilon, point[1] + epsilon, point[2] + epsilon)
179+
bbox.AddPoint(point[0] - epsilon, point[1] - epsilon, point[2] - epsilon)
180+
181+
array_ids = []
182+
for id in ids:
183+
bounds = self.get_object(id)["actor"].GetBounds()
184+
if bbox.Intersects(bounds):
185+
array_ids.append(id)
186+
187+
return {"array_ids": array_ids}

src/tests/test_viewer_protocols.py

Lines changed: 75 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,37 @@
77
# Local application imports
88
from .test_mesh_protocols import test_register_mesh
99

10+
1011
def test_create_visualization(server):
11-
server.call(VtkViewerView.prefix + VtkViewerView.schemas_dict["create_visualization"]["rpc"])
12+
server.call(
13+
VtkViewerView.prefix + VtkViewerView.schemas_dict["create_visualization"]["rpc"]
14+
)
1215
assert server.compare_image(3, "viewer/create_visualization.jpeg") == True
1316

17+
1418
def test_reset_camera(server):
15-
server.call(VtkViewerView.prefix + VtkViewerView.schemas_dict["reset_camera"]["rpc"])
19+
server.call(
20+
VtkViewerView.prefix + VtkViewerView.schemas_dict["reset_camera"]["rpc"]
21+
)
1622
assert server.compare_image(3, "viewer/reset_camera.jpeg") == True
1723

24+
1825
def test_set_viewer_background_color(server):
19-
server.call(VtkViewerView.prefix + VtkViewerView.schemas_dict["set_background_color"]["rpc"], [{"red": 0, "green": 0, "blue": 255}])
26+
server.call(
27+
VtkViewerView.prefix
28+
+ VtkViewerView.schemas_dict["set_background_color"]["rpc"],
29+
[{"red": 0, "green": 0, "blue": 255}],
30+
)
2031
assert server.compare_image(3, "viewer/set_background_color.jpeg") == True
2132

22-
def test_get_point_position(server):
2333

34+
def test_get_point_position(server):
2435
test_register_mesh(server)
2536

26-
server.call(VtkViewerView.prefix + VtkViewerView.schemas_dict["get_point_position"]["rpc"], [{"x": 0, "y": 0}])
37+
server.call(
38+
VtkViewerView.prefix + VtkViewerView.schemas_dict["get_point_position"]["rpc"],
39+
[{"x": 0, "y": 0}],
40+
)
2741
response = server.get_response()
2842
assert "x" in response["result"]
2943
assert "y" in response["result"]
@@ -43,7 +57,13 @@ def test_take_screenshot(server):
4357
# Take a screenshot with background jpg
4458
server.call(
4559
VtkViewerView.prefix + VtkViewerView.schemas_dict["take_screenshot"]["rpc"],
46-
[{"filename": "take_screenshot_with_background", "output_extension": "jpg", "include_background": True}],
60+
[
61+
{
62+
"filename": "take_screenshot_with_background",
63+
"output_extension": "jpg",
64+
"include_background": True,
65+
}
66+
],
4767
)
4868

4969
response = server.get_response()
@@ -54,16 +74,24 @@ def test_take_screenshot(server):
5474
f.write(blob)
5575
f.close()
5676
first_image_path = os.path.join(server.test_output_dir, "test.jpg")
57-
second_image_path = os.path.join(server.images_dir_path, "viewer/take_screenshot_with_background.jpg")
77+
second_image_path = os.path.join(
78+
server.images_dir_path, "viewer/take_screenshot_with_background.jpg"
79+
)
5880

5981
assert server.images_diff(first_image_path, second_image_path) == 0.0
6082

6183
# Take a screenshot without background png
6284
server.call(
6385
VtkViewerView.prefix + VtkViewerView.schemas_dict["take_screenshot"]["rpc"],
64-
[{"filename": "take_screenshot_without_background", "output_extension": "png", "include_background": True}],
86+
[
87+
{
88+
"filename": "take_screenshot_without_background",
89+
"output_extension": "png",
90+
"include_background": True,
91+
}
92+
],
6593
)
66-
94+
6795
response = server.get_response()
6896
response = server.get_response()
6997
blob = server.get_response()
@@ -74,16 +102,24 @@ def test_take_screenshot(server):
74102
f.write(blob)
75103
f.close()
76104
first_image_path = os.path.join(server.test_output_dir, "test.png")
77-
second_image_path = os.path.join(server.images_dir_path, "viewer/take_screenshot_without_background.png")
105+
second_image_path = os.path.join(
106+
server.images_dir_path, "viewer/take_screenshot_without_background.png"
107+
)
78108

79109
assert server.images_diff(first_image_path, second_image_path) == 0.0
80110

81111
# Take a screenshot with background png
82112
server.call(
83113
VtkViewerView.prefix + VtkViewerView.schemas_dict["take_screenshot"]["rpc"],
84-
[{"filename": "take_screenshot_with_background", "output_extension": "png", "include_background": True}],
114+
[
115+
{
116+
"filename": "take_screenshot_with_background",
117+
"output_extension": "png",
118+
"include_background": True,
119+
}
120+
],
85121
)
86-
122+
87123
response = server.get_response()
88124
response = server.get_response()
89125
blob = server.get_response()
@@ -94,6 +130,32 @@ def test_take_screenshot(server):
94130
f.write(blob)
95131
f.close()
96132
first_image_path = os.path.join(server.test_output_dir, "test.png")
97-
second_image_path = os.path.join(server.images_dir_path, "viewer/take_screenshot_with_background.png")
133+
second_image_path = os.path.join(
134+
server.images_dir_path, "viewer/take_screenshot_with_background.png"
135+
)
98136

99137
assert server.images_diff(first_image_path, second_image_path) == 0.0
138+
139+
140+
def test_picked_ids(server):
141+
142+
test_register_mesh(server)
143+
144+
server.call(
145+
VtkViewerView.prefix + VtkViewerView.schemas_dict["picked_ids"]["rpc"],
146+
[{"x": 100, "y": 200, "ids": ["123456789"]}],
147+
)
148+
response = server.get_response()
149+
150+
print(f"Response: {response}", flush=True)
151+
152+
assert "result" in response, f"Key 'result' not found in response: {response}"
153+
154+
assert (
155+
"array_ids" in response["result"]
156+
), f"Key 'array_ids' not found in response['result']: {response['result']}"
157+
158+
array_ids = response["result"]["array_ids"]
159+
assert isinstance(array_ids, list), f"Expected a list, but got {type(array_ids)}"
160+
assert all(isinstance(id, str) for id in array_ids), "All IDs should be strings"
161+
assert len(array_ids) > 0, "The list of array_ids should not be empty"

0 commit comments

Comments
 (0)