diff --git a/pyproject.toml b/pyproject.toml index 9ad3d4b..8dfcb18 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "OpenGeodeWeb-Viewer" -version = "1.7.1" +version = "1.8.0-rc.1" dynamic = ["dependencies"] authors = [ { name="Geode-solutions", email="team-web@geode-solutions.com" }, diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/render_now.json b/src/opengeodeweb_viewer/rpc/viewer/schemas/render_now.json new file mode 100644 index 0000000..ed6023d --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/render_now.json @@ -0,0 +1,7 @@ +{ + "rpc": "render_now", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false +} \ No newline at end of file diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/update_camera.json b/src/opengeodeweb_viewer/rpc/viewer/schemas/update_camera.json new file mode 100644 index 0000000..041b5f4 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/update_camera.json @@ -0,0 +1,56 @@ +{ + "rpc": "update_camera", + "type": "object", + "properties": { + "camera_options": { + "type": "object", + "properties": { + "focal_point": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3 + }, + "view_up": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3 + }, + "position": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3 + }, + "view_angle": { + "type": "number" + }, + "clipping_range": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 2, + "maxItems": 2 + } + }, + "required": [ + "focal_point", + "view_up", + "position", + "view_angle", + "clipping_range" + ] + } + }, + "required": [ + "camera_options" + ] +} \ No newline at end of file diff --git a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py index babb154..f78483e 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -248,3 +248,32 @@ def toggleAxes(self, params): actor = self.get_object(id)["actor"] actor.SetVisibility(visibility) self.render() + + @exportRpc(viewer_prefix + viewer_schemas_dict["update_camera"]["rpc"]) + def updateCamera(self, params): + validate_schema( + params, self.viewer_schemas_dict["update_camera"], self.viewer_prefix + ) + camera_options = params["camera_options"] + focal_point = camera_options["focal_point"] + view_up = camera_options["view_up"] + position = camera_options["position"] + view_angle = camera_options["view_angle"] + clipping_range = camera_options["clipping_range"] + + renderWindow = self.getView("-1") + camera = renderWindow.GetRenderers().GetFirstRenderer().GetActiveCamera() + + camera.SetFocalPoint(*focal_point) + camera.SetViewUp(*view_up) + camera.SetPosition(*position) + camera.SetViewAngle(view_angle) + camera.SetClippingRange(*clipping_range) + self.render() + + @exportRpc(viewer_prefix + viewer_schemas_dict["render_now"]["rpc"]) + def renderNow(self, params): + validate_schema( + params, self.viewer_schemas_dict["render_now"], self.viewer_prefix + ) + self.render() diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index d57715e..44dd12a 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -35,7 +35,7 @@ def render(self, view=-1): renderer_bounds = renderer.ComputeVisiblePropBounds() grid_scale = self.get_object("grid_scale")["actor"] grid_scale.SetBounds(renderer_bounds) - self.get_protocol("vtkWebPublishImageDelivery").imagePush({"view": view}) + self.getSharedObject("publisher").imagePush({"view": view}) def register_object(self, id, reader, filter, actor, mapper, textures): self.get_data_base()[id] = { diff --git a/src/opengeodeweb_viewer/vtkw_server.py b/src/opengeodeweb_viewer/vtkw_server.py index 7c44e7a..6805d0f 100644 --- a/src/opengeodeweb_viewer/vtkw_server.py +++ b/src/opengeodeweb_viewer/vtkw_server.py @@ -61,10 +61,11 @@ def initialize(self): # Bring used components self.registerVtkWebProtocol(vtk_protocols.vtkWebMouseHandler()) self.registerVtkWebProtocol(vtk_protocols.vtkWebViewPort()) - self.registerVtkWebProtocol( - vtk_protocols.vtkWebPublishImageDelivery(decode=False) - ) + publisher = vtk_protocols.vtkWebPublishImageDelivery(decode=False) + publisher.deltaStaleTimeBeforeRender = 0.1 + self.registerVtkWebProtocol(publisher) self.setSharedObject("db", dict()) + self.setSharedObject("publisher", publisher) # Custom API mesh_protocols = VtkMeshView() diff --git a/src/tests/data/images/viewer/render_now.jpeg b/src/tests/data/images/viewer/render_now.jpeg new file mode 100644 index 0000000..2791521 Binary files /dev/null and b/src/tests/data/images/viewer/render_now.jpeg differ diff --git a/src/tests/data/images/viewer/update_camera.jpeg b/src/tests/data/images/viewer/update_camera.jpeg new file mode 100644 index 0000000..2791521 Binary files /dev/null and b/src/tests/data/images/viewer/update_camera.jpeg differ diff --git a/src/tests/test_viewer_protocols.py b/src/tests/test_viewer_protocols.py index 01b15bf..b1ff472 100644 --- a/src/tests/test_viewer_protocols.py +++ b/src/tests/test_viewer_protocols.py @@ -204,3 +204,56 @@ def test_axes(server): ) assert server.compare_image(3, "viewer/axes_off.jpeg") == True + + +def test_update_camera(server): + test_register_mesh(server) + + camera_options = { + "focal_point": [-0.034399999999999986, 2.4513515, -0.10266900000000012], + "view_up": [0.48981180389508683, 0.8647097694977263, -0.11118188386706776], + "position": [-17.277630202755162, 13.419047188880267, 9.232808007244259], + "view_angle": 30.0, + "clipping_range": [11.403438348232822, 36.44815678922037], + } + + server.call( + VtkViewerView.viewer_prefix + + VtkViewerView.viewer_schemas_dict["update_camera"]["rpc"], + [ + { + "camera_options": camera_options, + } + ], + ) + assert server.compare_image(3, "viewer/update_camera.jpeg") == True + + +def test_render_now(server): + test_register_mesh(server) + + camera_options = { + "focal_point": [-0.034399999999999986, 2.4513515, -0.10266900000000012], + "view_up": [0.48981180389508683, 0.8647097694977263, -0.11118188386706776], + "position": [-17.277630202755162, 13.419047188880267, 9.232808007244259], + "view_angle": 30.0, + "clipping_range": [11.403438348232822, 36.44815678922037], + } + + server.call( + VtkViewerView.viewer_prefix + + VtkViewerView.viewer_schemas_dict["update_camera"]["rpc"], + [ + { + "camera_options": camera_options, + } + ], + ) + server.compare_image(1, "mesh/register.jpeg") + + server.call( + VtkViewerView.viewer_prefix + + VtkViewerView.viewer_schemas_dict["render_now"]["rpc"], + ) + + assert server.compare_image(3, "viewer/render_now.jpeg") == True