From d610feacc4fe58f85aaca115c5671b272503ad22 Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Thu, 20 Mar 2025 16:14:28 +0100 Subject: [PATCH 1/8] feat(viewer): add grid_scale protocol --- .../rpc/viewer/schemas/grid_scale.json | 13 ++++++ .../rpc/viewer/schemas/picked_ids.json | 46 +++++++++---------- .../rpc/viewer/viewer_protocols.py | 10 ++++ 3 files changed, 46 insertions(+), 23 deletions(-) create mode 100644 src/opengeodeweb_viewer/rpc/viewer/schemas/grid_scale.json diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/grid_scale.json b/src/opengeodeweb_viewer/rpc/viewer/schemas/grid_scale.json new file mode 100644 index 0000000..e885626 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/grid_scale.json @@ -0,0 +1,13 @@ +{ + "rpc": "grid_scale", + "type": "object", + "properties": { + "visibility": { + "type": "boolean" + } + }, + "required": [ + "visibility" + ], + "additionalProperties": false +} \ No newline at end of file diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/picked_ids.json b/src/opengeodeweb_viewer/rpc/viewer/schemas/picked_ids.json index 699ce50..10f89e0 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/schemas/picked_ids.json +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/picked_ids.json @@ -1,25 +1,25 @@ { - "rpc": "picked_ids", - "type": "object", - "properties": { - "x": { - "type": "number" - }, - "y": { - "type": "number" - }, - "ids": { - "type": "array", - "items": { - "type": "string", - "minLength": 1 - } - } - }, - "required": [ - "x", - "y", - "ids" - ], - "additionalProperties": false + "rpc": "picked_ids", + "type": "object", + "properties": { + "x": { + "type": "number" + }, + "y": { + "type": "number" + }, + "ids": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + } + }, + "required": [ + "x", + "y", + "ids" + ], + "additionalProperties": false } \ 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 2fba8eb..6770fec 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -192,3 +192,13 @@ def pickedIds(self, params): array_ids.append(id) return {"array_ids": array_ids} + + @exportRpc(viewer_prefix + viewer_schemas_dict["grid_scale"]["rpc"]) + def updateData(self, params): + validate_schema( + params, self.viewer_schemas_dict["grid_scale"], self.viewer_prefix + ) + id, visibility = "grid_scale", params["visibility"] + actor = self.get_object(id)["actor"] + actor.SetVisibility(visibility) + self.render() From 2f9b67ac3a5e36b6563ff5a77ca0c6455ff4dfb5 Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Thu, 20 Mar 2025 16:14:53 +0100 Subject: [PATCH 2/8] register grid_scale in db --- src/opengeodeweb_viewer/vtkw_server.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/opengeodeweb_viewer/vtkw_server.py b/src/opengeodeweb_viewer/vtkw_server.py index da35460..4f627d1 100644 --- a/src/opengeodeweb_viewer/vtkw_server.py +++ b/src/opengeodeweb_viewer/vtkw_server.py @@ -6,6 +6,7 @@ import vtk from vtk.web import wslink as vtk_wslink from vtk.web import protocols as vtk_protocols +from vtkmodules.vtkRenderingAnnotation import vtkCubeAxesActor from wslink import server # Local application imports @@ -69,7 +70,8 @@ def initialize(self): # Custom API mesh_protocols = VtkMeshView() model_protocols = VtkModelView() - self.registerVtkWebProtocol(VtkView()) + vtk_view = VtkView() + self.registerVtkWebProtocol(vtk_view) self.registerVtkWebProtocol(VtkViewerView()) self.registerVtkWebProtocol(mesh_protocols) self.registerVtkWebProtocol(VtkMeshPointsView()) @@ -106,6 +108,22 @@ def initialize(self): widget.SetInteractor(renderWindowInteractor) widget.SetViewport(0.0, 0.0, 0.2, 0.2) axes = vtk.vtkAxesActor() + + grid_scale = vtkCubeAxesActor(camera=renderer.active_camera) + grid_scale.DrawXGridlinesOn() + grid_scale.DrawYGridlinesOn() + grid_scale.DrawZGridlinesOn() + grid_scale.SetGridLineLocation(grid_scale.VTK_GRID_LINES_FURTHEST) + grid_scale.GetTitleTextProperty(0).SetColor(255, 255, 255) + grid_scale.GetTitleTextProperty(1).SetColor(255, 255, 255) + grid_scale.GetTitleTextProperty(2).SetColor(255, 255, 255) + grid_scale.SetFlyModeToStaticEdges() + vtk_view.register_object("grid_scale", "", "", grid_scale, "", "") + grid_scale_actor = vtk_view.get_object("grid_scale")["actor"] + grid_scale_actor.SetVisibility(False) + + renderer.AddActor(grid_scale) + widget.SetOrientationMarker(axes) widget.EnabledOn() widget.InteractiveOff() From c739b4b4c22b7aae3752ebd4dd8b757fb030020f Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Thu, 20 Mar 2025 16:15:08 +0100 Subject: [PATCH 3/8] wip tests --- src/tests/test_viewer_protocols.py | 37 ++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/tests/test_viewer_protocols.py b/src/tests/test_viewer_protocols.py index ecf8f23..f95f099 100644 --- a/src/tests/test_viewer_protocols.py +++ b/src/tests/test_viewer_protocols.py @@ -166,3 +166,40 @@ def test_picked_ids(server): assert isinstance(array_ids, list), f"Expected a list, but got {type(array_ids)}" assert all(isinstance(id, str) for id in array_ids), "All IDs should be strings" assert len(array_ids) > 0, "The list of array_ids should not be empty" + + +def test_grid_scale(server): + + test_register_mesh(server) + + server.call( + VtkViewerView.viewer_prefix + + VtkViewerView.viewer_schemas_dict["set_background_color"]["rpc"], + [{"color": {"r": 60, "g": 60, "b": 60}}], + ) + + assert server.compare_image(3, "viewer/grid_scale_off.jpeg") == True + + # assert server.compare_image(3, "viewer/grid_scale_off.jpeg") == True + + # server.call( + # VtkViewerView.viewer_prefix + # + VtkViewerView.viewer_schemas_dict["grid_scale"]["rpc"], + # [{"visibility": True}], + # ) + + # assert server.compare_image(3, "viewer/grid_scale_on.jpeg") == True + + # server.call( + # VtkViewerView.viewer_prefix + # + VtkViewerView.viewer_schemas_dict["set_background_color"]["rpc"], + # [{"color": {"r": 0, "g": 0, "b": 255}}], + # ) + + # server.call( + # VtkViewerView.viewer_prefix + # + VtkViewerView.viewer_schemas_dict["grid_scale"]["rpc"], + # [{"visibility": False}], + # ) + + # assert server.compare_image(3, "viewer/grid_scale_off.jpeg") == True From 6b0f90b465807bafbb8ed8fcdb1915dc1025389e Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Thu, 20 Mar 2025 16:15:35 +0100 Subject: [PATCH 4/8] compute new bound in render --- src/opengeodeweb_viewer/vtk_protocol.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index 292a4ff..b610f10 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -30,6 +30,12 @@ def get_protocol(self, name): return p def render(self, view=-1): + renderer = self.get_renderer() + renderer_bounds = renderer.ComputeVisiblePropBounds() + grid_scale = self.get_object("grid_scale")["actor"] + grid_scale.SetBounds(renderer_bounds) + grid_scale.Modified() + self.get_protocol("vtkWebPublishImageDelivery").imagePush({"view": view}) def register_object(self, id, reader, filter, actor, mapper, textures): From 201f82e545b3c22fb7ed33b16d21a74072f1fac7 Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Thu, 20 Mar 2025 16:17:01 +0100 Subject: [PATCH 5/8] fix SetBackground /255 --- src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py index 6770fec..6080028 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -47,7 +47,7 @@ def setBackgroundColor(self, params): renderWindow = self.getView("-1") renderer = renderWindow.GetRenderers().GetFirstRenderer() - renderer.SetBackground([red, green, blue]) + renderer.SetBackground([red / 255, green / 255, blue / 255]) renderer.ResetCamera() renderWindow.Render() self.render() From 2c42968136942dce63aeb8bee10ab610706f50be Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Mon, 24 Mar 2025 16:30:20 +0100 Subject: [PATCH 6/8] feat(viewer): dynamic grid scale --- CHANGELOG.md | 2 +- pyproject.toml | 16 ++-- .../polyhedra_protocols.py} | 42 +++++------ .../schemas/color.json | 0 .../schemas/polyhedron_attribute.json | 0 .../schemas/vertex_attribute.json | 0 .../schemas/visibility.json | 0 ...drons_protocols.py => blocks_protocols.py} | 26 +++---- .../{polyhedrons => }/schemas/color.json | 0 .../{polyhedrons => }/schemas/visibility.json | 0 ...ints_protocols.py => corners_protocols.py} | 20 ++--- .../corners/{points => }/schemas/color.json | 0 .../{points => }/schemas/visibility.json | 0 ..._edges_protocols.py => lines_protocols.py} | 18 ++--- .../lines/{edges => }/schemas/color.json | 0 .../lines/{edges => }/schemas/visibility.json | 0 .../schemas/apply_textures.json | 0 .../{polygons => }/schemas/color.json | 0 .../{polygons => }/schemas/visibility.json | 0 ...ons_protocols.py => surfaces_protocols.py} | 22 +++--- .../viewer/schemas/create_visualization.json | 7 -- .../{reset.json => reset_visualization.json} | 2 +- .../rpc/viewer/viewer_protocols.py | 41 +++++++--- src/opengeodeweb_viewer/vtk_protocol.py | 11 ++- src/opengeodeweb_viewer/vtkw_server.py | 44 ++++------- .../{polyhedrons => polyhedra}/color.jpeg | Bin .../polyhedron_attribute.jpeg | Bin .../{polyhedrons => polyhedra}/register.jpeg | Bin .../vertex_attribute.jpeg | Bin .../visibility.jpeg | Bin .../model/blocks/{polyhedrons => }/color.jpeg | Bin .../blocks/{polyhedrons => }/visibility.jpeg | Bin .../model/corners/{points => }/color.jpeg | Bin .../corners/{points => }/visibility.jpeg | Bin .../images/model/lines/{edges => }/color.jpeg | Bin .../model/lines/{edges => }/visibility.jpeg | Bin .../model/surfaces/{polygons => }/color.jpeg | Bin .../surfaces/{polygons => }/visibility.jpeg | Bin .../data/images/viewer/grid_scale_on.jpeg | Bin 0 -> 24009 bytes .../data/images/viewer/register_hat.jpeg | Bin 0 -> 10766 bytes src/tests/data/images/viewer/reset.jpeg | Bin 2131 -> 0 bytes ...lization.jpeg => reset_visualization.jpeg} | Bin .../polyhedra/test_polyhedra_protocols.py | 70 ++++++++++++++++++ .../polyhedrons/test_polyhedrons_protocols.py | 70 ------------------ ...cols.py => test_model_blocks_protocols.py} | 26 +++---- ...ols.py => test_model_corners_protocols.py} | 20 ++--- ...ocols.py => test_model_lines_protocols.py} | 20 ++--- ...ls.py => test_model_surfaces_protocols.py} | 20 ++--- src/tests/test_viewer_protocols.py | 47 +++++------- 49 files changed, 254 insertions(+), 270 deletions(-) rename src/opengeodeweb_viewer/rpc/mesh/{polyhedrons/polyhedrons_protocols.py => polyhedra/polyhedra_protocols.py} (50%) rename src/opengeodeweb_viewer/rpc/mesh/{polyhedrons => polyhedra}/schemas/color.json (100%) rename src/opengeodeweb_viewer/rpc/mesh/{polyhedrons => polyhedra}/schemas/polyhedron_attribute.json (100%) rename src/opengeodeweb_viewer/rpc/mesh/{polyhedrons => polyhedra}/schemas/vertex_attribute.json (100%) rename src/opengeodeweb_viewer/rpc/mesh/{polyhedrons => polyhedra}/schemas/visibility.json (100%) rename src/opengeodeweb_viewer/rpc/model/blocks/{polyhedrons/blocks_polyhedrons_protocols.py => blocks_protocols.py} (57%) rename src/opengeodeweb_viewer/rpc/model/blocks/{polyhedrons => }/schemas/color.json (100%) rename src/opengeodeweb_viewer/rpc/model/blocks/{polyhedrons => }/schemas/visibility.json (100%) rename src/opengeodeweb_viewer/rpc/model/corners/{points/corners_points_protocols.py => corners_protocols.py} (65%) rename src/opengeodeweb_viewer/rpc/model/corners/{points => }/schemas/color.json (100%) rename src/opengeodeweb_viewer/rpc/model/corners/{points => }/schemas/visibility.json (100%) rename src/opengeodeweb_viewer/rpc/model/lines/{edges/lines_edges_protocols.py => lines_protocols.py} (67%) rename src/opengeodeweb_viewer/rpc/model/lines/{edges => }/schemas/color.json (100%) rename src/opengeodeweb_viewer/rpc/model/lines/{edges => }/schemas/visibility.json (100%) rename src/opengeodeweb_viewer/rpc/model/surfaces/{polygons => }/schemas/apply_textures.json (100%) rename src/opengeodeweb_viewer/rpc/model/surfaces/{polygons => }/schemas/color.json (100%) rename src/opengeodeweb_viewer/rpc/model/surfaces/{polygons => }/schemas/visibility.json (100%) rename src/opengeodeweb_viewer/rpc/model/surfaces/{polygons/surfaces_polygons_protocols.py => surfaces_protocols.py} (64%) delete mode 100644 src/opengeodeweb_viewer/rpc/viewer/schemas/create_visualization.json rename src/opengeodeweb_viewer/rpc/viewer/schemas/{reset.json => reset_visualization.json} (74%) rename src/tests/data/images/mesh/{polyhedrons => polyhedra}/color.jpeg (100%) rename src/tests/data/images/mesh/{polyhedrons => polyhedra}/polyhedron_attribute.jpeg (100%) rename src/tests/data/images/mesh/{polyhedrons => polyhedra}/register.jpeg (100%) rename src/tests/data/images/mesh/{polyhedrons => polyhedra}/vertex_attribute.jpeg (100%) rename src/tests/data/images/mesh/{polyhedrons => polyhedra}/visibility.jpeg (100%) rename src/tests/data/images/model/blocks/{polyhedrons => }/color.jpeg (100%) rename src/tests/data/images/model/blocks/{polyhedrons => }/visibility.jpeg (100%) rename src/tests/data/images/model/corners/{points => }/color.jpeg (100%) rename src/tests/data/images/model/corners/{points => }/visibility.jpeg (100%) rename src/tests/data/images/model/lines/{edges => }/color.jpeg (100%) rename src/tests/data/images/model/lines/{edges => }/visibility.jpeg (100%) rename src/tests/data/images/model/surfaces/{polygons => }/color.jpeg (100%) rename src/tests/data/images/model/surfaces/{polygons => }/visibility.jpeg (100%) create mode 100644 src/tests/data/images/viewer/grid_scale_on.jpeg create mode 100644 src/tests/data/images/viewer/register_hat.jpeg delete mode 100644 src/tests/data/images/viewer/reset.jpeg rename src/tests/data/images/viewer/{create_visualization.jpeg => reset_visualization.jpeg} (100%) create mode 100644 src/tests/mesh/polyhedra/test_polyhedra_protocols.py delete mode 100644 src/tests/mesh/polyhedrons/test_polyhedrons_protocols.py rename src/tests/model/blocks/{polyhedrons/test_model_blocks_polyhedrons_protocols.py => test_model_blocks_protocols.py} (52%) rename src/tests/model/corners/{points/test_model_corners_points_protocols.py => test_model_corners_protocols.py} (59%) rename src/tests/model/lines/{edges/test_model_lines_edges_protocols.py => test_model_lines_protocols.py} (59%) rename src/tests/model/surfaces/{polygons/test_model_surfaces_polygons_protocols.py => test_model_surfaces_protocols.py} (60%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 290197b..5f4c03a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,7 +65,7 @@ ### Features -- **polyhedrons**: Color protocol +- **polyhedra**: Color protocol ([`15b35fc`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/15b35fcfdda1afc66f4eb4942d9f54006bbc9a0f)) diff --git a/pyproject.toml b/pyproject.toml index 4bfbd14..ef96248 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,18 +41,12 @@ where = ["src"] "opengeodeweb_viewer.rpc.mesh.points.schemas" = ["*.json"] "opengeodeweb_viewer.rpc.mesh.edges.schemas" = ["*.json"] "opengeodeweb_viewer.rpc.mesh.polygons.schemas" = ["*.json"] -"opengeodeweb_viewer.rpc.mesh.polyhedrons.schemas" = ["*.json"] +"opengeodeweb_viewer.rpc.mesh.polyhedra.schemas" = ["*.json"] "opengeodeweb_viewer.rpc.model.schemas" = ["*.json"] -"opengeodeweb_viewer.rpc.model.corners.points.schemas" = ["*.json"] -"opengeodeweb_viewer.rpc.model.lines.points.schemas" = ["*.json"] -"opengeodeweb_viewer.rpc.model.lines.edges.schemas" = ["*.json"] -"opengeodeweb_viewer.rpc.model.surfaces.points.schemas" = ["*.json"] -"opengeodeweb_viewer.rpc.model.surfaces.edges.schemas" = ["*.json"] -"opengeodeweb_viewer.rpc.model.surfaces.polygons.schemas" = ["*.json"] -"opengeodeweb_viewer.rpc.model.blocks.points.schemas" = ["*.json"] -"opengeodeweb_viewer.rpc.model.blocks.edges.schemas" = ["*.json"] -"opengeodeweb_viewer.rpc.model.blocks.polygons.schemas" = ["*.json"] -"opengeodeweb_viewer.rpc.model.blocks.polyhedrons.schemas" = ["*.json"] +"opengeodeweb_viewer.rpc.model.corners.schemas" = ["*.json"] +"opengeodeweb_viewer.rpc.model.lines.schemas" = ["*.json"] +"opengeodeweb_viewer.rpc.model.surfaces.schemas" = ["*.json"] +"opengeodeweb_viewer.rpc.model.blocks.schemas" = ["*.json"] "opengeodeweb_viewer.rpc.viewer.schemas" = ["*.json"] [tool.semantic_release] diff --git a/src/opengeodeweb_viewer/rpc/mesh/polyhedrons/polyhedrons_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/polyhedra_protocols.py similarity index 50% rename from src/opengeodeweb_viewer/rpc/mesh/polyhedrons/polyhedrons_protocols.py rename to src/opengeodeweb_viewer/rpc/mesh/polyhedra/polyhedra_protocols.py index ed99e8d..2415fb1 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/polyhedrons/polyhedrons_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/polyhedra_protocols.py @@ -9,9 +9,9 @@ from opengeodeweb_viewer.rpc.mesh.mesh_protocols import VtkMeshView -class VtkMeshPolyhedronsView(VtkMeshView): - mesh_polyhedrons_prefix = "opengeodeweb_viewer.mesh.polyhedrons." - mesh_polyhedrons_schemas_dict = get_schemas_dict( +class VtkMeshPolyhedraView(VtkMeshView): + mesh_polyhedra_prefix = "opengeodeweb_viewer.mesh.polyhedra." + mesh_polyhedra_schemas_dict = get_schemas_dict( os.path.join(os.path.dirname(__file__), "schemas") ) @@ -19,23 +19,23 @@ def __init__(self): super().__init__() @exportRpc( - mesh_polyhedrons_prefix + mesh_polyhedrons_schemas_dict["visibility"]["rpc"] + mesh_polyhedra_prefix + mesh_polyhedra_schemas_dict["visibility"]["rpc"] ) - def setMeshPolyhedronsVisibility(self, params): + def setMeshPolyhedraVisibility(self, params): validate_schema( params, - self.mesh_polyhedrons_schemas_dict["visibility"], - self.mesh_polyhedrons_prefix, + self.mesh_polyhedra_schemas_dict["visibility"], + self.mesh_polyhedra_prefix, ) id, visibility = params["id"], params["visibility"] self.SetVisibility(id, visibility) - @exportRpc(mesh_polyhedrons_prefix + mesh_polyhedrons_schemas_dict["color"]["rpc"]) - def setMeshPolyhedronsColor(self, params): + @exportRpc(mesh_polyhedra_prefix + mesh_polyhedra_schemas_dict["color"]["rpc"]) + def setMeshPolyhedraColor(self, params): validate_schema( params, - self.mesh_polyhedrons_schemas_dict["color"], - self.mesh_polyhedrons_prefix, + self.mesh_polyhedra_schemas_dict["color"], + self.mesh_polyhedra_prefix, ) id, red, green, blue = ( params["id"], @@ -46,27 +46,27 @@ def setMeshPolyhedronsColor(self, params): self.SetColor(id, red, green, blue) @exportRpc( - mesh_polyhedrons_prefix - + mesh_polyhedrons_schemas_dict["vertex_attribute"]["rpc"] + mesh_polyhedra_prefix + + mesh_polyhedra_schemas_dict["vertex_attribute"]["rpc"] ) - def setMeshPolyhedronsVertexAttribute(self, params): + def setMeshPolyhedraVertexAttribute(self, params): validate_schema( params, - self.mesh_polyhedrons_schemas_dict["vertex_attribute"], - self.mesh_polyhedrons_prefix, + self.mesh_polyhedra_schemas_dict["vertex_attribute"], + self.mesh_polyhedra_prefix, ) id, name = params["id"], params["name"] self.displayAttributeOnVertices(id, name) @exportRpc( - mesh_polyhedrons_prefix - + mesh_polyhedrons_schemas_dict["polyhedron_attribute"]["rpc"] + mesh_polyhedra_prefix + + mesh_polyhedra_schemas_dict["polyhedron_attribute"]["rpc"] ) - def setMeshPolyhedronsPolyhedronAttribute(self, params): + def setMeshPolyhedraPolyhedronAttribute(self, params): validate_schema( params, - self.mesh_polyhedrons_schemas_dict["polyhedron_attribute"], - self.mesh_polyhedrons_prefix, + self.mesh_polyhedra_schemas_dict["polyhedron_attribute"], + self.mesh_polyhedra_prefix, ) id, name = params["id"], params["name"] self.displayAttributeOnCells(id, name) diff --git a/src/opengeodeweb_viewer/rpc/mesh/polyhedrons/schemas/color.json b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/color.json similarity index 100% rename from src/opengeodeweb_viewer/rpc/mesh/polyhedrons/schemas/color.json rename to src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/color.json diff --git a/src/opengeodeweb_viewer/rpc/mesh/polyhedrons/schemas/polyhedron_attribute.json b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/polyhedron_attribute.json similarity index 100% rename from src/opengeodeweb_viewer/rpc/mesh/polyhedrons/schemas/polyhedron_attribute.json rename to src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/polyhedron_attribute.json diff --git a/src/opengeodeweb_viewer/rpc/mesh/polyhedrons/schemas/vertex_attribute.json b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/vertex_attribute.json similarity index 100% rename from src/opengeodeweb_viewer/rpc/mesh/polyhedrons/schemas/vertex_attribute.json rename to src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/vertex_attribute.json diff --git a/src/opengeodeweb_viewer/rpc/mesh/polyhedrons/schemas/visibility.json b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/visibility.json similarity index 100% rename from src/opengeodeweb_viewer/rpc/mesh/polyhedrons/schemas/visibility.json rename to src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/visibility.json diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/polyhedrons/blocks_polyhedrons_protocols.py b/src/opengeodeweb_viewer/rpc/model/blocks/blocks_protocols.py similarity index 57% rename from src/opengeodeweb_viewer/rpc/model/blocks/polyhedrons/blocks_polyhedrons_protocols.py rename to src/opengeodeweb_viewer/rpc/model/blocks/blocks_protocols.py index 931c992..31495a9 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/polyhedrons/blocks_polyhedrons_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/blocks_protocols.py @@ -9,9 +9,9 @@ from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView -class VtkModelBlocksPolyhedronsView(VtkModelView): - model_blocks_polyhedrons_prefix = "opengeodeweb_viewer.model.blocks.polyhedrons." - model_blocks_polyhedrons_schemas_dict = get_schemas_dict( +class VtkModelBlocksView(VtkModelView): + model_blocks_prefix = "opengeodeweb_viewer.model.blocks." + model_blocks_schemas_dict = get_schemas_dict( os.path.join(os.path.dirname(__file__), "schemas") ) @@ -19,14 +19,14 @@ def __init__(self): super().__init__() @exportRpc( - model_blocks_polyhedrons_prefix - + model_blocks_polyhedrons_schemas_dict["visibility"]["rpc"] + model_blocks_prefix + + model_blocks_schemas_dict["visibility"]["rpc"] ) - def setModelBlocksPolyhedronsVisibility(self, params): + def setModelBlocksPolyhedraVisibility(self, params): validate_schema( params, - self.model_blocks_polyhedrons_schemas_dict["visibility"], - self.model_blocks_polyhedrons_prefix, + self.model_blocks_schemas_dict["visibility"], + self.model_blocks_prefix, ) id, block_ids, visibility = ( params["id"], @@ -36,14 +36,14 @@ def setModelBlocksPolyhedronsVisibility(self, params): self.SetBlocksVisibility(id, block_ids, visibility) @exportRpc( - model_blocks_polyhedrons_prefix - + model_blocks_polyhedrons_schemas_dict["color"]["rpc"] + model_blocks_prefix + + model_blocks_schemas_dict["color"]["rpc"] ) - def setModelBlocksPolyhedronsColor(self, params): + def setModelBlocksPolyhedraColor(self, params): validate_schema( params, - self.model_blocks_polyhedrons_schemas_dict["color"], - self.model_blocks_polyhedrons_prefix, + self.model_blocks_schemas_dict["color"], + self.model_blocks_prefix, ) id, block_ids, red, green, blue = ( params["id"], diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/polyhedrons/schemas/color.json b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.json similarity index 100% rename from src/opengeodeweb_viewer/rpc/model/blocks/polyhedrons/schemas/color.json rename to src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.json diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/polyhedrons/schemas/visibility.json b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/visibility.json similarity index 100% rename from src/opengeodeweb_viewer/rpc/model/blocks/polyhedrons/schemas/visibility.json rename to src/opengeodeweb_viewer/rpc/model/blocks/schemas/visibility.json diff --git a/src/opengeodeweb_viewer/rpc/model/corners/points/corners_points_protocols.py b/src/opengeodeweb_viewer/rpc/model/corners/corners_protocols.py similarity index 65% rename from src/opengeodeweb_viewer/rpc/model/corners/points/corners_points_protocols.py rename to src/opengeodeweb_viewer/rpc/model/corners/corners_protocols.py index 04b870d..5c09f72 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/points/corners_points_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/corners_protocols.py @@ -9,9 +9,9 @@ from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView -class VtkModelCornersPointsView(VtkModelView): - model_corners_points_prefix = "opengeodeweb_viewer.model.corners.points." - model_corners_points_schemas_dict = get_schemas_dict( +class VtkModelCornersView(VtkModelView): + model_corners_prefix = "opengeodeweb_viewer.model.corners." + model_corners_schemas_dict = get_schemas_dict( os.path.join(os.path.dirname(__file__), "schemas") ) @@ -19,14 +19,14 @@ def __init__(self): super().__init__() @exportRpc( - model_corners_points_prefix - + model_corners_points_schemas_dict["visibility"]["rpc"] + model_corners_prefix + + model_corners_schemas_dict["visibility"]["rpc"] ) def setModelCornersPointsVisibility(self, params): validate_schema( params, - self.model_corners_points_schemas_dict["visibility"], - self.model_corners_points_prefix, + self.model_corners_schemas_dict["visibility"], + self.model_corners_prefix, ) id, block_ids, visibility = ( params["id"], @@ -36,13 +36,13 @@ def setModelCornersPointsVisibility(self, params): self.SetBlocksVisibility(id, block_ids, visibility) @exportRpc( - model_corners_points_prefix + model_corners_points_schemas_dict["color"]["rpc"] + model_corners_prefix + model_corners_schemas_dict["color"]["rpc"] ) def setModelCornersPointsColor(self, params): validate_schema( params, - self.model_corners_points_schemas_dict["color"], - self.model_corners_points_prefix, + self.model_corners_schemas_dict["color"], + self.model_corners_prefix, ) id, block_ids, red, green, blue = ( params["id"], diff --git a/src/opengeodeweb_viewer/rpc/model/corners/points/schemas/color.json b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.json similarity index 100% rename from src/opengeodeweb_viewer/rpc/model/corners/points/schemas/color.json rename to src/opengeodeweb_viewer/rpc/model/corners/schemas/color.json diff --git a/src/opengeodeweb_viewer/rpc/model/corners/points/schemas/visibility.json b/src/opengeodeweb_viewer/rpc/model/corners/schemas/visibility.json similarity index 100% rename from src/opengeodeweb_viewer/rpc/model/corners/points/schemas/visibility.json rename to src/opengeodeweb_viewer/rpc/model/corners/schemas/visibility.json diff --git a/src/opengeodeweb_viewer/rpc/model/lines/edges/lines_edges_protocols.py b/src/opengeodeweb_viewer/rpc/model/lines/lines_protocols.py similarity index 67% rename from src/opengeodeweb_viewer/rpc/model/lines/edges/lines_edges_protocols.py rename to src/opengeodeweb_viewer/rpc/model/lines/lines_protocols.py index dc75cea..5e6b431 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/edges/lines_edges_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/lines_protocols.py @@ -9,9 +9,9 @@ from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView -class VtkModelLinesEdgesView(VtkModelView): - model_lines_edges_prefix = "opengeodeweb_viewer.model.lines.edges." - model_lines_edges_schemas_dict = get_schemas_dict( +class VtkModelLinesView(VtkModelView): + model_lines_prefix = "opengeodeweb_viewer.model.lines." + model_lines_schemas_dict = get_schemas_dict( os.path.join(os.path.dirname(__file__), "schemas") ) @@ -19,13 +19,13 @@ def __init__(self): super().__init__() @exportRpc( - model_lines_edges_prefix + model_lines_edges_schemas_dict["visibility"]["rpc"] + model_lines_prefix + model_lines_schemas_dict["visibility"]["rpc"] ) def setModelLinesEdgesVisibility(self, params): validate_schema( params, - self.model_lines_edges_schemas_dict["visibility"], - self.model_lines_edges_prefix, + self.model_lines_schemas_dict["visibility"], + self.model_lines_prefix, ) id, block_ids, visibility = ( params["id"], @@ -35,13 +35,13 @@ def setModelLinesEdgesVisibility(self, params): self.SetBlocksVisibility(id, block_ids, visibility) @exportRpc( - model_lines_edges_prefix + model_lines_edges_schemas_dict["color"]["rpc"] + model_lines_prefix + model_lines_schemas_dict["color"]["rpc"] ) def setModelLinesEdgesColor(self, params): validate_schema( params, - self.model_lines_edges_schemas_dict["color"], - self.model_lines_edges_prefix, + self.model_lines_schemas_dict["color"], + self.model_lines_prefix, ) id, block_ids, red, green, blue = ( params["id"], diff --git a/src/opengeodeweb_viewer/rpc/model/lines/edges/schemas/color.json b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.json similarity index 100% rename from src/opengeodeweb_viewer/rpc/model/lines/edges/schemas/color.json rename to src/opengeodeweb_viewer/rpc/model/lines/schemas/color.json diff --git a/src/opengeodeweb_viewer/rpc/model/lines/edges/schemas/visibility.json b/src/opengeodeweb_viewer/rpc/model/lines/schemas/visibility.json similarity index 100% rename from src/opengeodeweb_viewer/rpc/model/lines/edges/schemas/visibility.json rename to src/opengeodeweb_viewer/rpc/model/lines/schemas/visibility.json diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/polygons/schemas/apply_textures.json b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/apply_textures.json similarity index 100% rename from src/opengeodeweb_viewer/rpc/model/surfaces/polygons/schemas/apply_textures.json rename to src/opengeodeweb_viewer/rpc/model/surfaces/schemas/apply_textures.json diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/polygons/schemas/color.json b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.json similarity index 100% rename from src/opengeodeweb_viewer/rpc/model/surfaces/polygons/schemas/color.json rename to src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.json diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/polygons/schemas/visibility.json b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/visibility.json similarity index 100% rename from src/opengeodeweb_viewer/rpc/model/surfaces/polygons/schemas/visibility.json rename to src/opengeodeweb_viewer/rpc/model/surfaces/schemas/visibility.json diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/polygons/surfaces_polygons_protocols.py b/src/opengeodeweb_viewer/rpc/model/surfaces/surfaces_protocols.py similarity index 64% rename from src/opengeodeweb_viewer/rpc/model/surfaces/polygons/surfaces_polygons_protocols.py rename to src/opengeodeweb_viewer/rpc/model/surfaces/surfaces_protocols.py index fc51ac7..e3d6531 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/polygons/surfaces_polygons_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/surfaces_protocols.py @@ -9,9 +9,9 @@ from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView -class VtkModelSurfacesPolygonsView(VtkModelView): - model_surfaces_polygons_prefix = "opengeodeweb_viewer.model.surfaces.polygons." - model_surfaces_polygons_schemas_dict = get_schemas_dict( +class VtkModelSurfacesView(VtkModelView): + model_surfaces_prefix = "opengeodeweb_viewer.model.surfaces." + model_surfaces_schemas_dict = get_schemas_dict( os.path.join(os.path.dirname(__file__), "schemas") ) @@ -19,14 +19,14 @@ def __init__(self): super().__init__() @exportRpc( - model_surfaces_polygons_prefix - + model_surfaces_polygons_schemas_dict["visibility"]["rpc"] + model_surfaces_prefix + + model_surfaces_schemas_dict["visibility"]["rpc"] ) def setModelSurfacesPolygonsVisibility(self, params): validate_schema( params, - self.model_surfaces_polygons_schemas_dict["visibility"], - self.model_surfaces_polygons_prefix, + self.model_surfaces_schemas_dict["visibility"], + self.model_surfaces_prefix, ) id, block_ids, visibility = ( params["id"], @@ -36,14 +36,14 @@ def setModelSurfacesPolygonsVisibility(self, params): self.SetBlocksVisibility(id, block_ids, visibility) @exportRpc( - model_surfaces_polygons_prefix - + model_surfaces_polygons_schemas_dict["color"]["rpc"] + model_surfaces_prefix + + model_surfaces_schemas_dict["color"]["rpc"] ) def setModelSurfacesPolygonsCOlor(self, params): validate_schema( params, - self.model_surfaces_polygons_schemas_dict["color"], - self.model_surfaces_polygons_prefix, + self.model_surfaces_schemas_dict["color"], + self.model_surfaces_prefix, ) id, block_ids, red, green, blue = ( params["id"], diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/create_visualization.json b/src/opengeodeweb_viewer/rpc/viewer/schemas/create_visualization.json deleted file mode 100644 index 532d711..0000000 --- a/src/opengeodeweb_viewer/rpc/viewer/schemas/create_visualization.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "rpc": "create_visualization", - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false -} \ No newline at end of file diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/reset.json b/src/opengeodeweb_viewer/rpc/viewer/schemas/reset_visualization.json similarity index 74% rename from src/opengeodeweb_viewer/rpc/viewer/schemas/reset.json rename to src/opengeodeweb_viewer/rpc/viewer/schemas/reset_visualization.json index c1977cb..cfc8ff5 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/schemas/reset.json +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/reset_visualization.json @@ -1,5 +1,5 @@ { - "rpc": "reset", + "rpc": "reset_visualization", "type": "object", "properties": {}, "required": [], diff --git a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py index 6080028..f976c4a 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -5,6 +5,7 @@ # Third party imports import vtk from vtkmodules.vtkIOImage import vtkPNGWriter, vtkJPEGWriter +from vtkmodules.vtkRenderingAnnotation import vtkCubeAxesActor from vtkmodules.vtkRenderingCore import vtkWindowToImageFilter from wslink import register as exportRpc @@ -22,14 +23,42 @@ class VtkViewerView(VtkView): def __init__(self): super().__init__() - @exportRpc(viewer_prefix + viewer_schemas_dict["create_visualization"]["rpc"]) - def createVisualization(self, params): + @exportRpc(viewer_prefix + viewer_schemas_dict["reset_visualization"]["rpc"]) + def resetVisualization(self, params): validate_schema( - params, self.viewer_schemas_dict["create_visualization"], self.viewer_prefix + params, self.viewer_schemas_dict["reset_visualization"], self.viewer_prefix ) renderWindow = self.getView("-1") renderer = renderWindow.GetRenderers().GetFirstRenderer() + renderer.RemoveAllViewProps() + + grid_scale = vtkCubeAxesActor() + grid_scale.SetCamera(renderer.GetActiveCamera()) + grid_scale.DrawXGridlinesOn() + grid_scale.DrawYGridlinesOn() + grid_scale.DrawZGridlinesOn() + grid_scale.SetGridLineLocation(grid_scale.VTK_GRID_LINES_FURTHEST) + grid_scale.GetTitleTextProperty(0).SetColor(0, 0, 0) + grid_scale.GetTitleTextProperty(1).SetColor(0, 0, 0) + grid_scale.GetTitleTextProperty(2).SetColor(0, 0, 0) + grid_scale.GetXAxesLinesProperty().SetColor(0, 0, 0) + grid_scale.GetYAxesLinesProperty().SetColor(0, 0, 0) + grid_scale.GetZAxesLinesProperty().SetColor(0, 0, 0) + grid_scale.GetLabelTextProperty(0).SetColor(0, 0, 0) + grid_scale.GetLabelTextProperty(1).SetColor(0, 0, 0) + grid_scale.GetLabelTextProperty(2).SetColor(0, 0, 0) + grid_scale.GetXAxesGridlinesProperty().SetColor(0, 0, 0) + grid_scale.GetYAxesGridlinesProperty().SetColor(0, 0, 0) + grid_scale.GetZAxesGridlinesProperty().SetColor(0, 0, 0) + + grid_scale.SetVisibility(False) + # grid_scale.SetFlyModeToStaticEdges() + self.register_object("grid_scale", "", "", grid_scale, "", "") + + + renderer.AddActor(grid_scale) renderer.SetBackground([180 / 255, 180 / 255, 180 / 255]) + renderer.ResetCamera() renderWindow.Render() self.render() @@ -147,12 +176,6 @@ def getPointPosition(self, params): ppos = picker.GetPickPosition() return {"x": ppos[0], "y": ppos[1], "z": ppos[2]} - @exportRpc(viewer_prefix + viewer_schemas_dict["reset"]["rpc"]) - def reset(self, params): - validate_schema(params, self.viewer_schemas_dict["reset"], self.viewer_prefix) - renderWindow = self.getView("-1") - renderWindow.GetRenderers().GetFirstRenderer().RemoveAllViewProps() - def computeEpsilon(self, renderer, z): renderer.SetDisplayPoint(0, 0, z) renderer.DisplayToWorld() diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index b610f10..d57715e 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -30,12 +30,11 @@ def get_protocol(self, name): return p def render(self, view=-1): - renderer = self.get_renderer() - renderer_bounds = renderer.ComputeVisiblePropBounds() - grid_scale = self.get_object("grid_scale")["actor"] - grid_scale.SetBounds(renderer_bounds) - grid_scale.Modified() - + if "grid_scale" in self.get_data_base(): + renderer = self.get_renderer() + renderer_bounds = renderer.ComputeVisiblePropBounds() + grid_scale = self.get_object("grid_scale")["actor"] + grid_scale.SetBounds(renderer_bounds) self.get_protocol("vtkWebPublishImageDelivery").imagePush({"view": view}) def register_object(self, id, reader, filter, actor, mapper, textures): diff --git a/src/opengeodeweb_viewer/vtkw_server.py b/src/opengeodeweb_viewer/vtkw_server.py index 4f627d1..9f967bc 100644 --- a/src/opengeodeweb_viewer/vtkw_server.py +++ b/src/opengeodeweb_viewer/vtkw_server.py @@ -6,7 +6,6 @@ import vtk from vtk.web import wslink as vtk_wslink from vtk.web import protocols as vtk_protocols -from vtkmodules.vtkRenderingAnnotation import vtkCubeAxesActor from wslink import server # Local application imports @@ -17,19 +16,19 @@ from .rpc.mesh.points.mesh_points_protocols import VtkMeshPointsView from .rpc.mesh.edges.mesh_edges_protocols import VtkMeshEdgesView from .rpc.mesh.polygons.polygons_protocols import VtkMeshPolygonsView -from .rpc.mesh.polyhedrons.polyhedrons_protocols import VtkMeshPolyhedronsView +from .rpc.mesh.polyhedra.polyhedra_protocols import VtkMeshPolyhedraView from .rpc.model.model_protocols import VtkModelView -from .rpc.model.corners.points.corners_points_protocols import ( - VtkModelCornersPointsView, +from .rpc.model.corners.corners_protocols import ( + VtkModelCornersView, ) -from .rpc.model.lines.edges.lines_edges_protocols import ( - VtkModelLinesEdgesView, +from .rpc.model.lines.lines_protocols import ( + VtkModelLinesView, ) -from .rpc.model.surfaces.polygons.surfaces_polygons_protocols import ( - VtkModelSurfacesPolygonsView, +from .rpc.model.surfaces.surfaces_protocols import ( + VtkModelSurfacesView, ) -from .rpc.model.blocks.polyhedrons.blocks_polyhedrons_protocols import ( - VtkModelBlocksPolyhedronsView, +from .rpc.model.blocks.blocks_protocols import ( + VtkModelBlocksView, ) from .rpc.generic.generic_protocols import VtkGenericView @@ -77,12 +76,12 @@ def initialize(self): self.registerVtkWebProtocol(VtkMeshPointsView()) self.registerVtkWebProtocol(VtkMeshEdgesView()) self.registerVtkWebProtocol(VtkMeshPolygonsView()) - self.registerVtkWebProtocol(VtkMeshPolyhedronsView()) + self.registerVtkWebProtocol(VtkMeshPolyhedraView()) self.registerVtkWebProtocol(model_protocols) - self.registerVtkWebProtocol(VtkModelCornersPointsView()) - self.registerVtkWebProtocol(VtkModelLinesEdgesView()) - self.registerVtkWebProtocol(VtkModelSurfacesPolygonsView()) - self.registerVtkWebProtocol(VtkModelBlocksPolyhedronsView()) + self.registerVtkWebProtocol(VtkModelCornersView()) + self.registerVtkWebProtocol(VtkModelLinesView()) + self.registerVtkWebProtocol(VtkModelSurfacesView()) + self.registerVtkWebProtocol(VtkModelBlocksView()) self.registerVtkWebProtocol(VtkGenericView(mesh_protocols, model_protocols)) # tell the C++ web app to use no encoding. @@ -109,21 +108,6 @@ def initialize(self): widget.SetViewport(0.0, 0.0, 0.2, 0.2) axes = vtk.vtkAxesActor() - grid_scale = vtkCubeAxesActor(camera=renderer.active_camera) - grid_scale.DrawXGridlinesOn() - grid_scale.DrawYGridlinesOn() - grid_scale.DrawZGridlinesOn() - grid_scale.SetGridLineLocation(grid_scale.VTK_GRID_LINES_FURTHEST) - grid_scale.GetTitleTextProperty(0).SetColor(255, 255, 255) - grid_scale.GetTitleTextProperty(1).SetColor(255, 255, 255) - grid_scale.GetTitleTextProperty(2).SetColor(255, 255, 255) - grid_scale.SetFlyModeToStaticEdges() - vtk_view.register_object("grid_scale", "", "", grid_scale, "", "") - grid_scale_actor = vtk_view.get_object("grid_scale")["actor"] - grid_scale_actor.SetVisibility(False) - - renderer.AddActor(grid_scale) - widget.SetOrientationMarker(axes) widget.EnabledOn() widget.InteractiveOff() diff --git a/src/tests/data/images/mesh/polyhedrons/color.jpeg b/src/tests/data/images/mesh/polyhedra/color.jpeg similarity index 100% rename from src/tests/data/images/mesh/polyhedrons/color.jpeg rename to src/tests/data/images/mesh/polyhedra/color.jpeg diff --git a/src/tests/data/images/mesh/polyhedrons/polyhedron_attribute.jpeg b/src/tests/data/images/mesh/polyhedra/polyhedron_attribute.jpeg similarity index 100% rename from src/tests/data/images/mesh/polyhedrons/polyhedron_attribute.jpeg rename to src/tests/data/images/mesh/polyhedra/polyhedron_attribute.jpeg diff --git a/src/tests/data/images/mesh/polyhedrons/register.jpeg b/src/tests/data/images/mesh/polyhedra/register.jpeg similarity index 100% rename from src/tests/data/images/mesh/polyhedrons/register.jpeg rename to src/tests/data/images/mesh/polyhedra/register.jpeg diff --git a/src/tests/data/images/mesh/polyhedrons/vertex_attribute.jpeg b/src/tests/data/images/mesh/polyhedra/vertex_attribute.jpeg similarity index 100% rename from src/tests/data/images/mesh/polyhedrons/vertex_attribute.jpeg rename to src/tests/data/images/mesh/polyhedra/vertex_attribute.jpeg diff --git a/src/tests/data/images/mesh/polyhedrons/visibility.jpeg b/src/tests/data/images/mesh/polyhedra/visibility.jpeg similarity index 100% rename from src/tests/data/images/mesh/polyhedrons/visibility.jpeg rename to src/tests/data/images/mesh/polyhedra/visibility.jpeg diff --git a/src/tests/data/images/model/blocks/polyhedrons/color.jpeg b/src/tests/data/images/model/blocks/color.jpeg similarity index 100% rename from src/tests/data/images/model/blocks/polyhedrons/color.jpeg rename to src/tests/data/images/model/blocks/color.jpeg diff --git a/src/tests/data/images/model/blocks/polyhedrons/visibility.jpeg b/src/tests/data/images/model/blocks/visibility.jpeg similarity index 100% rename from src/tests/data/images/model/blocks/polyhedrons/visibility.jpeg rename to src/tests/data/images/model/blocks/visibility.jpeg diff --git a/src/tests/data/images/model/corners/points/color.jpeg b/src/tests/data/images/model/corners/color.jpeg similarity index 100% rename from src/tests/data/images/model/corners/points/color.jpeg rename to src/tests/data/images/model/corners/color.jpeg diff --git a/src/tests/data/images/model/corners/points/visibility.jpeg b/src/tests/data/images/model/corners/visibility.jpeg similarity index 100% rename from src/tests/data/images/model/corners/points/visibility.jpeg rename to src/tests/data/images/model/corners/visibility.jpeg diff --git a/src/tests/data/images/model/lines/edges/color.jpeg b/src/tests/data/images/model/lines/color.jpeg similarity index 100% rename from src/tests/data/images/model/lines/edges/color.jpeg rename to src/tests/data/images/model/lines/color.jpeg diff --git a/src/tests/data/images/model/lines/edges/visibility.jpeg b/src/tests/data/images/model/lines/visibility.jpeg similarity index 100% rename from src/tests/data/images/model/lines/edges/visibility.jpeg rename to src/tests/data/images/model/lines/visibility.jpeg diff --git a/src/tests/data/images/model/surfaces/polygons/color.jpeg b/src/tests/data/images/model/surfaces/color.jpeg similarity index 100% rename from src/tests/data/images/model/surfaces/polygons/color.jpeg rename to src/tests/data/images/model/surfaces/color.jpeg diff --git a/src/tests/data/images/model/surfaces/polygons/visibility.jpeg b/src/tests/data/images/model/surfaces/visibility.jpeg similarity index 100% rename from src/tests/data/images/model/surfaces/polygons/visibility.jpeg rename to src/tests/data/images/model/surfaces/visibility.jpeg diff --git a/src/tests/data/images/viewer/grid_scale_on.jpeg b/src/tests/data/images/viewer/grid_scale_on.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..cb6ac367d1019825aa038bdf36c3cc1aa9437ab2 GIT binary patch literal 24009 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 G%>EB4u=U0O literal 0 HcmV?d00001 diff --git a/src/tests/data/images/viewer/register_hat.jpeg b/src/tests/data/images/viewer/register_hat.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..e5c17451811c02418472795af1d0d6ed46c8681d GIT binary patch literal 10766 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 nqb(k5I7?=bZ znFSgDA7PLJI+7VE%YXo^>>O;ITtGQVpfFGlA;ZAH#LU9V_Wu?G4>KbJlK`^-(3d~| zBP$q2Y$h+!mwVRcUJ>4a>?zjSk!2P?t>t;6=a}rB_xrO|o^Ut^vI0D8eqf*~2rw|R zFfjqc4+dBmnOWJG*ck$Z#0nMw!rXaL&`JR&TKxh`rcIip`>L}f_xMWjusfaFMH8p8O>xWF@V4jn!f2nP zA)eC|-8qdsH+;GM{Vv#QEdgM9Wng4xVq=7c0x;Nt=~qxlSVWOQRLRgOK-oDk2_EQd z_Dug7+Ph*Fl)LrW*2eCtIdysS)5as8KNYWddF|4#e4ba+PQA67mMhW4_P0daMy5FZ z%%qPKg?@K$=t)d-y#7*&!^}bC_)Z?f3C3^P;w%43|26WxH*0gA{pMex6EB~71k5O} zW$#PRF%-RFc*6X{H~skTR)*4oRaq+~Cp#a$RdBk>v0}~H`N>NfzC1PL;lEVG(K(~( zvDHLd_4o1zzyJHsAfEH)W1nr^a}#Y-i^=Og`mB!nSs9n;wqLvMcgAMFEz*w+f9$eN zV!!h1uSlnBh7?Z*?G~?_e3L$&5HI&U*JEeg z>G|i$zRZ()mt}5Wt$40@NaW((2Q?|LSA}=SYp2XF56V1sJ3~KU0ng7;d*S~Ku8Y}a zYx6?)e4O_}f_d}f7l&T|;LpE$`Thfor|ZfWr}yiIUXaj#@~iI{%N2vvP_}595ZBNd zOXrpzvJT2-is9)vqaCfEp&7sIgx0pAEwRzAJToSK3ahOb4mVIWaM{-BaOU{aca}L9 zc2zbO?qZx%HZR2K_q8qiK3thRh4;9sS8&duKWCz@u@xy8%D=7$CUhAAV0HoKCs^tN zmPmpOiiQD>@MvYUSNu_VW8=b-tLO9@1de2gt-EWWGFSD%#DF7jJ@mSokI8)d)}(2( zZd&3w6;Y;h!cNUnK@ZISGi)+EtfFnkaHzo{H(>|En$F|S6JJc|7PK-hyzY7F!>5Y} zF7qzswtU2_)0=1}nw5J#n&nCYPxic*FXFx)T_z7JB!StGfdN=f4omO@*;kCg#Fm51 zpm-Am7juYW5EyTY42BK?iHLGZ;79eb5>eKZN{t~F`3c3rd|g2SGkIs-nUmR(zD)a%V=h%DU-GCTLBJKWI6}(=BqT%@Hr& zpdy9jr;{zr7$zw&EO@#6X Date: Mon, 24 Mar 2025 15:33:42 +0000 Subject: [PATCH 7/8] Apply prepare changes --- .../rpc/mesh/polyhedra/polyhedra_protocols.py | 7 ++----- .../rpc/model/blocks/blocks_protocols.py | 10 ++-------- .../rpc/model/corners/corners_protocols.py | 9 ++------- .../rpc/model/lines/lines_protocols.py | 8 ++------ .../rpc/model/surfaces/surfaces_protocols.py | 10 ++-------- .../rpc/viewer/viewer_protocols.py | 1 - src/tests/mesh/polyhedra/test_polyhedra_protocols.py | 4 +--- .../model/blocks/test_model_blocks_protocols.py | 12 +++--------- .../model/corners/test_model_corners_protocols.py | 8 ++------ .../model/surfaces/test_model_surfaces_protocols.py | 12 +++--------- src/tests/test_viewer_protocols.py | 4 +--- 11 files changed, 20 insertions(+), 65 deletions(-) diff --git a/src/opengeodeweb_viewer/rpc/mesh/polyhedra/polyhedra_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/polyhedra_protocols.py index 2415fb1..a805d99 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/polyhedra/polyhedra_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/polyhedra_protocols.py @@ -18,9 +18,7 @@ class VtkMeshPolyhedraView(VtkMeshView): def __init__(self): super().__init__() - @exportRpc( - mesh_polyhedra_prefix + mesh_polyhedra_schemas_dict["visibility"]["rpc"] - ) + @exportRpc(mesh_polyhedra_prefix + mesh_polyhedra_schemas_dict["visibility"]["rpc"]) def setMeshPolyhedraVisibility(self, params): validate_schema( params, @@ -46,8 +44,7 @@ def setMeshPolyhedraColor(self, params): self.SetColor(id, red, green, blue) @exportRpc( - mesh_polyhedra_prefix - + mesh_polyhedra_schemas_dict["vertex_attribute"]["rpc"] + mesh_polyhedra_prefix + mesh_polyhedra_schemas_dict["vertex_attribute"]["rpc"] ) def setMeshPolyhedraVertexAttribute(self, params): validate_schema( diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/blocks_protocols.py b/src/opengeodeweb_viewer/rpc/model/blocks/blocks_protocols.py index 31495a9..eee2811 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/blocks_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/blocks_protocols.py @@ -18,10 +18,7 @@ class VtkModelBlocksView(VtkModelView): def __init__(self): super().__init__() - @exportRpc( - model_blocks_prefix - + model_blocks_schemas_dict["visibility"]["rpc"] - ) + @exportRpc(model_blocks_prefix + model_blocks_schemas_dict["visibility"]["rpc"]) def setModelBlocksPolyhedraVisibility(self, params): validate_schema( params, @@ -35,10 +32,7 @@ def setModelBlocksPolyhedraVisibility(self, params): ) self.SetBlocksVisibility(id, block_ids, visibility) - @exportRpc( - model_blocks_prefix - + model_blocks_schemas_dict["color"]["rpc"] - ) + @exportRpc(model_blocks_prefix + model_blocks_schemas_dict["color"]["rpc"]) def setModelBlocksPolyhedraColor(self, params): validate_schema( params, diff --git a/src/opengeodeweb_viewer/rpc/model/corners/corners_protocols.py b/src/opengeodeweb_viewer/rpc/model/corners/corners_protocols.py index 5c09f72..3e0df02 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/corners_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/corners_protocols.py @@ -18,10 +18,7 @@ class VtkModelCornersView(VtkModelView): def __init__(self): super().__init__() - @exportRpc( - model_corners_prefix - + model_corners_schemas_dict["visibility"]["rpc"] - ) + @exportRpc(model_corners_prefix + model_corners_schemas_dict["visibility"]["rpc"]) def setModelCornersPointsVisibility(self, params): validate_schema( params, @@ -35,9 +32,7 @@ def setModelCornersPointsVisibility(self, params): ) self.SetBlocksVisibility(id, block_ids, visibility) - @exportRpc( - model_corners_prefix + model_corners_schemas_dict["color"]["rpc"] - ) + @exportRpc(model_corners_prefix + model_corners_schemas_dict["color"]["rpc"]) def setModelCornersPointsColor(self, params): validate_schema( params, diff --git a/src/opengeodeweb_viewer/rpc/model/lines/lines_protocols.py b/src/opengeodeweb_viewer/rpc/model/lines/lines_protocols.py index 5e6b431..afec4e6 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/lines_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/lines_protocols.py @@ -18,9 +18,7 @@ class VtkModelLinesView(VtkModelView): def __init__(self): super().__init__() - @exportRpc( - model_lines_prefix + model_lines_schemas_dict["visibility"]["rpc"] - ) + @exportRpc(model_lines_prefix + model_lines_schemas_dict["visibility"]["rpc"]) def setModelLinesEdgesVisibility(self, params): validate_schema( params, @@ -34,9 +32,7 @@ def setModelLinesEdgesVisibility(self, params): ) self.SetBlocksVisibility(id, block_ids, visibility) - @exportRpc( - model_lines_prefix + model_lines_schemas_dict["color"]["rpc"] - ) + @exportRpc(model_lines_prefix + model_lines_schemas_dict["color"]["rpc"]) def setModelLinesEdgesColor(self, params): validate_schema( params, diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/surfaces_protocols.py b/src/opengeodeweb_viewer/rpc/model/surfaces/surfaces_protocols.py index e3d6531..1a73e27 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/surfaces_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/surfaces_protocols.py @@ -18,10 +18,7 @@ class VtkModelSurfacesView(VtkModelView): def __init__(self): super().__init__() - @exportRpc( - model_surfaces_prefix - + model_surfaces_schemas_dict["visibility"]["rpc"] - ) + @exportRpc(model_surfaces_prefix + model_surfaces_schemas_dict["visibility"]["rpc"]) def setModelSurfacesPolygonsVisibility(self, params): validate_schema( params, @@ -35,10 +32,7 @@ def setModelSurfacesPolygonsVisibility(self, params): ) self.SetBlocksVisibility(id, block_ids, visibility) - @exportRpc( - model_surfaces_prefix - + model_surfaces_schemas_dict["color"]["rpc"] - ) + @exportRpc(model_surfaces_prefix + model_surfaces_schemas_dict["color"]["rpc"]) def setModelSurfacesPolygonsCOlor(self, params): validate_schema( params, diff --git a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py index f976c4a..d67450a 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -55,7 +55,6 @@ def resetVisualization(self, params): # grid_scale.SetFlyModeToStaticEdges() self.register_object("grid_scale", "", "", grid_scale, "", "") - renderer.AddActor(grid_scale) renderer.SetBackground([180 / 255, 180 / 255, 180 / 255]) diff --git a/src/tests/mesh/polyhedra/test_polyhedra_protocols.py b/src/tests/mesh/polyhedra/test_polyhedra_protocols.py index 6e37876..50a4532 100644 --- a/src/tests/mesh/polyhedra/test_polyhedra_protocols.py +++ b/src/tests/mesh/polyhedra/test_polyhedra_protocols.py @@ -48,9 +48,7 @@ def test_vertex_attribute(server): server.call( VtkMeshPolyhedraView.mesh_polyhedra_prefix - + VtkMeshPolyhedraView.mesh_polyhedra_schemas_dict["vertex_attribute"][ - "rpc" - ], + + VtkMeshPolyhedraView.mesh_polyhedra_schemas_dict["vertex_attribute"]["rpc"], [{"id": "123456789", "name": "toto_on_vertices"}], ) assert server.compare_image(3, "mesh/polyhedra/vertex_attribute.jpeg") == True diff --git a/src/tests/model/blocks/test_model_blocks_protocols.py b/src/tests/model/blocks/test_model_blocks_protocols.py index e4074f0..457a215 100644 --- a/src/tests/model/blocks/test_model_blocks_protocols.py +++ b/src/tests/model/blocks/test_model_blocks_protocols.py @@ -15,9 +15,7 @@ def test_blocks_polyhedra_visibility(server): server.call( VtkModelBlocksView.model_blocks_prefix - + VtkModelBlocksView.model_blocks_schemas_dict[ - "visibility" - ]["rpc"], + + VtkModelBlocksView.model_blocks_schemas_dict["visibility"]["rpc"], [ { "id": "123456789", @@ -31,9 +29,7 @@ def test_blocks_polyhedra_visibility(server): server.call( VtkModelBlocksView.model_blocks_prefix - + VtkModelBlocksView.model_blocks_schemas_dict[ - "visibility" - ]["rpc"], + + VtkModelBlocksView.model_blocks_schemas_dict["visibility"]["rpc"], [ { "id": "123456789", @@ -52,9 +48,7 @@ def test_blocks_polyhedra_color(server): server.call( VtkModelBlocksView.model_blocks_prefix - + VtkModelBlocksView.model_blocks_schemas_dict["color"][ - "rpc" - ], + + VtkModelBlocksView.model_blocks_schemas_dict["color"]["rpc"], [ { "id": "123456789", diff --git a/src/tests/model/corners/test_model_corners_protocols.py b/src/tests/model/corners/test_model_corners_protocols.py index aa35461..14f27aa 100644 --- a/src/tests/model/corners/test_model_corners_protocols.py +++ b/src/tests/model/corners/test_model_corners_protocols.py @@ -15,9 +15,7 @@ def test_corners_points_visibility(server): server.call( VtkModelCornersView.model_corners_prefix - + VtkModelCornersView.model_corners_schemas_dict["visibility"][ - "rpc" - ], + + VtkModelCornersView.model_corners_schemas_dict["visibility"]["rpc"], [ { "id": "123456789", @@ -30,9 +28,7 @@ def test_corners_points_visibility(server): server.call( VtkModelCornersView.model_corners_prefix - + VtkModelCornersView.model_corners_schemas_dict["visibility"][ - "rpc" - ], + + VtkModelCornersView.model_corners_schemas_dict["visibility"]["rpc"], [ { "id": "123456789", diff --git a/src/tests/model/surfaces/test_model_surfaces_protocols.py b/src/tests/model/surfaces/test_model_surfaces_protocols.py index 3331ebd..309daa0 100644 --- a/src/tests/model/surfaces/test_model_surfaces_protocols.py +++ b/src/tests/model/surfaces/test_model_surfaces_protocols.py @@ -15,9 +15,7 @@ def test_surfaces_polygons_visibility(server): server.call( VtkModelSurfacesView.model_surfaces_prefix - + VtkModelSurfacesView.model_surfaces_schemas_dict[ - "visibility" - ]["rpc"], + + VtkModelSurfacesView.model_surfaces_schemas_dict["visibility"]["rpc"], [ { "id": "123456789", @@ -30,9 +28,7 @@ def test_surfaces_polygons_visibility(server): server.call( VtkModelSurfacesView.model_surfaces_prefix - + VtkModelSurfacesView.model_surfaces_schemas_dict[ - "visibility" - ]["rpc"], + + VtkModelSurfacesView.model_surfaces_schemas_dict["visibility"]["rpc"], [ { "id": "123456789", @@ -51,9 +47,7 @@ def test_surfaces_polygons_color(server): server.call( VtkModelSurfacesView.model_surfaces_prefix - + VtkModelSurfacesView.model_surfaces_schemas_dict["color"][ - "rpc" - ], + + VtkModelSurfacesView.model_surfaces_schemas_dict["color"]["rpc"], [ { "id": "123456789", diff --git a/src/tests/test_viewer_protocols.py b/src/tests/test_viewer_protocols.py index 414b4cb..ba2de04 100644 --- a/src/tests/test_viewer_protocols.py +++ b/src/tests/test_viewer_protocols.py @@ -172,7 +172,6 @@ def test_picked_ids(server): def test_grid_scale(server): - server.call( VtkViewerView.viewer_prefix + VtkViewerView.viewer_schemas_dict["reset_visualization"]["rpc"], @@ -185,7 +184,7 @@ def test_grid_scale(server): [{"id": "123456789", "file_name": "hat.vtp"}], ) assert server.compare_image(3, "viewer/register_hat.jpeg") == True - + server.call( VtkViewerView.viewer_prefix + VtkViewerView.viewer_schemas_dict["grid_scale"]["rpc"], @@ -193,4 +192,3 @@ def test_grid_scale(server): ) assert server.compare_image(3, "viewer/grid_scale_on.jpeg") == True - From 3e7c3a02be6638a30e003fb019ca421755a0d413 Mon Sep 17 00:00:00 2001 From: semantic-release Date: Mon, 24 Mar 2025 15:39:39 +0000 Subject: [PATCH 8/8] 1.6.0-rc.1 Automatically generated by python-semantic-release --- CHANGELOG.md | 13 ++++++++++++- pyproject.toml | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f4c03a..7c26add 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ # CHANGELOG +## v1.6.0-rc.1 (2025-03-24) + +### Features + +- **viewer**: Add grid_scale protocol + ([`d610fea`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/d610feacc4fe58f85aaca115c5671b272503ad22)) + +- **viewer**: Dynamic grid scale + ([`2c42968`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/2c42968136942dce63aeb8bee10ab610706f50be)) + + ## v1.5.0 (2025-03-19) @@ -65,7 +76,7 @@ ### Features -- **polyhedra**: Color protocol +- **polyhedrons**: Color protocol ([`15b35fc`](https://github.com/Geode-solutions/OpenGeodeWeb-Viewer/commit/15b35fcfdda1afc66f4eb4942d9f54006bbc9a0f)) diff --git a/pyproject.toml b/pyproject.toml index ef96248..fe548e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "OpenGeodeWeb-Viewer" -version = "1.5.0" +version = "1.6.0-rc.1" dynamic = ["dependencies"] authors = [ { name="Geode-solutions", email="team-web@geode-solutions.com" },