From 61200cdf2df89e0e09563b0e28e7d547bc5955ae Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Wed, 13 May 2026 16:09:20 +0200 Subject: [PATCH 01/18] temp schemas and logic --- opengeodeweb_viewer_schemas.json | 33 ++++++++++ .../object/object_methods.py | 18 ++++++ .../rpc/mesh/mesh_protocols.py | 5 ++ .../rpc/model/model_protocols.py | 3 + .../rpc/viewer/schemas/__init__.py | 1 + .../rpc/viewer/schemas/hover_highlight.json | 24 +++++++ .../rpc/viewer/schemas/hover_highlight.py | 20 ++++++ .../rpc/viewer/viewer_protocols.py | 63 ++++++++++++++++++- src/opengeodeweb_viewer/vtk_protocol.py | 14 ++++- 9 files changed, 178 insertions(+), 3 deletions(-) create mode 100644 src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.json create mode 100644 src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.py diff --git a/opengeodeweb_viewer_schemas.json b/opengeodeweb_viewer_schemas.json index 3a3aef75..5e658c00 100644 --- a/opengeodeweb_viewer_schemas.json +++ b/opengeodeweb_viewer_schemas.json @@ -1905,6 +1905,39 @@ ], "additionalProperties": false }, + "hover_highlight": { + "$id": "opengeodeweb_viewer.viewer.hover_highlight", + "rpc": "hover_highlight", + "type": "object", + "properties": { + "x": { + "type": "number" + }, + "y": { + "type": "number" + }, + "field_type": { + "enum": [ + "CELL", + "POINT" + ] + }, + "ids": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + } + }, + "required": [ + "x", + "y", + "field_type", + "ids" + ], + "additionalProperties": false + }, "grid_scale": { "$id": "opengeodeweb_viewer.viewer.grid_scale", "rpc": "grid_scale", diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index 6e6899b3..2106deff 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -48,6 +48,7 @@ def registerObject( resetCamara = False renderer.AddActor(data.actor) renderer.AddActor(data.highlightActor) + renderer.AddActor(data.hoverHighlightActor) if resetCamara: renderer.ResetCamera() @@ -57,6 +58,7 @@ def deregisterObject(self, data_id: str) -> None: renderer = renderWindow.GetRenderers().GetFirstRenderer() renderer.RemoveActor(pipeline.actor) renderer.RemoveActor(pipeline.highlightActor) + renderer.RemoveActor(pipeline.hoverHighlightActor) self.deregister_object(data_id) def SetVisibility(self, data_id: str, visibility: bool) -> None: @@ -178,3 +180,19 @@ def highlight( prop.SetEdgeColor(0.12, 0.35, 0.30) actor.SetMapper(mapper) actor.VisibilityOff() + + def HoverHighlight( + self, actor: vtkActor, mapper: vtkDataSetMapper, input_dataset: vtkDataObject + ) -> None: + mapper.ScalarVisibilityOff() + mapper.SetResolveCoincidentTopologyToPolygonOffset() + prop = actor.GetProperty() + prop.SetColor(1, 0.5, 0) + prop.SetLineWidth(5) + prop.SetPointSize(16) + prop.SetRenderPointsAsSpheres(True) + prop.SetLighting(False) + prop.SetEdgeVisibility(True) + prop.SetEdgeColor(1, 0.5, 0) + actor.SetMapper(mapper) + actor.VisibilityOff() diff --git a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py index ce7e3a67..5b6f8e4e 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py @@ -55,6 +55,11 @@ def registerMesh(self, rpc_params: RpcParams) -> None: self.highlight( data.highlightActor, data.highlightMapper, reader.GetOutputDataObject(0) ) + self.HoverHighlight( + data.hoverHighlightActor, + data.hoverHighlightMapper, + reader.GetOutputDataObject(0), + ) self.registerObject(data_id, file_name, data) except Exception as e: print(f"Error registering mesh {data_id}: {str(e)}", flush=True) diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index d7d9d504..2c0114f8 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -124,6 +124,9 @@ def registerModel(self, rpc_params: RpcParams) -> None: ) data = VtkPipeline(reader, highlight_mapper, mapper, filter) self.highlight(data.highlightActor, data.highlightMapper, geometry_output) + self.HoverHighlight( + data.hoverHighlightActor, data.hoverHighlightMapper, geometry_output + ) iterator = geometry_output.NewTreeIterator() iterator.InitTraversal() while not iterator.IsDoneWithTraversal(): diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py index aa88dcf8..dc64d6ce 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py @@ -7,6 +7,7 @@ from .reset_camera import * from .render import * from .picked_ids import * +from .hover_highlight import * from .grid_scale import * from .get_point_position import * from .axes import * diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.json b/src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.json new file mode 100644 index 00000000..365cf0fd --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.json @@ -0,0 +1,24 @@ +{ + "rpc": "hover_highlight", + "type": "object", + "properties": { + "x": { + "type": "number" + }, + "y": { + "type": "number" + }, + "field_type": { + "enum": ["CELL", "POINT"] + }, + "ids": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + } + }, + "required": ["x", "y", "field_type", "ids"], + "additionalProperties": false +} diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.py new file mode 100644 index 00000000..f256a026 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.py @@ -0,0 +1,20 @@ +from dataclasses_json import DataClassJsonMixin +from enum import Enum +from dataclasses import dataclass +from typing import List + + +class FieldType(Enum): + CELL = "CELL" + POINT = "POINT" + + +@dataclass +class HoverHighlight(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + field_type: FieldType + ids: List[str] + x: float + y: float diff --git a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py index c2153d96..bc51ddfc 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -19,8 +19,8 @@ vtkCompositePolyDataMapper, ) from vtkmodules.vtkInteractionStyle import vtkInteractorStyleTrackball -from vtkmodules.vtkCommonCore import reference -from vtkmodules.vtkCommonDataModel import vtkBoundingBox, vtkDataSet +from vtkmodules.vtkCommonCore import reference, vtkIdTypeArray +from vtkmodules.vtkCommonDataModel import vtkBoundingBox, vtkDataSet, vtkSelectionNode from vtkmodules.vtkCommonTransforms import vtkTransform from vtkmodules.vtkInteractionWidgets import vtkOrientationMarkerWidget from opengeodeweb_microservice.schemas import get_schemas_dict @@ -303,6 +303,65 @@ def renderNow(self, rpc_params: RpcParams) -> None: ) self.render() + @exportRpc(viewer_prefix + viewer_schemas_dict["hover_highlight"]["rpc"]) + def setHoverHighlight(self, rpc_params: RpcParams) -> None: + validate_schema( + rpc_params, self.viewer_schemas_dict["hover_highlight"], self.viewer_prefix + ) + params = schemas.HoverHighlight.from_dict(rpc_params) + renderer = self.get_renderer() + picker = vtkCellPicker(tolerance=0.005) + picker.Pick(params.x, params.y, 0, renderer) + actor = picker.GetActor() + for data_id in params.ids: + pipeline = self.get_vtk_pipeline(data_id) + pipeline.hoverHighlightActor.VisibilityOff() + if actor: + for data_id in params.ids: + pipeline = self.get_vtk_pipeline(data_id) + if pipeline.actor == actor: + cell_id = picker.GetCellId() + point_id = picker.GetPointId() + + id_to_select = ( + cell_id + if params.field_type == schemas.FieldType.CELL + else point_id + ) + if id_to_select != -1: + node = pipeline.selectionNode + node.SetContentType(vtkSelectionNode.INDICES) + if params.field_type == schemas.FieldType.CELL: + node.SetFieldType(vtkSelectionNode.CELL) + else: + node.SetFieldType(vtkSelectionNode.POINT) + + selection_list = vtkIdTypeArray() + selection_list.SetNumberOfComponents(1) + selection_list.InsertNextValue(id_to_select) + node.SetSelectionList(selection_list) + + selection = pipeline.selection + if selection.GetNumberOfNodes() == 0: + selection.AddNode(node) + + extract = pipeline.extractSelection + input_port = ( + pipeline.filter.GetOutputPort() + if pipeline.filter + else pipeline.reader.GetOutputPort() + ) + extract.SetInputConnection(0, input_port) + extract.SetInputData(1, selection) + extract.Update() + + pipeline.hoverHighlightMapper.SetInputConnection( + extract.GetOutputPort() + ) + pipeline.hoverHighlightActor.VisibilityOn() + break + self.render(-1) + @exportRpc(viewer_prefix + viewer_schemas_dict["set_z_scaling"]["rpc"]) def setZScaling(self, rpc_params: RpcParams) -> None: validate_schema( diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index 603fb5ea..01c8dc8f 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -18,8 +18,15 @@ vtkRenderer, vtkRenderWindow, vtkCompositePolyDataMapper, + vtkDataSetMapper, ) -from vtkmodules.vtkCommonDataModel import vtkDataObject, vtkBoundingBox +from vtkmodules.vtkCommonDataModel import ( + vtkDataObject, + vtkBoundingBox, + vtkSelection, + vtkSelectionNode, +) +from vtkmodules.vtkFiltersExtraction import vtkExtractSelection from vtkmodules.vtkCommonCore import vtkStringArray from vtkmodules.vtkRenderingAnnotation import vtkCubeAxesActor, vtkAxesActor from vtkmodules.vtkInteractionWidgets import vtkOrientationMarkerWidget @@ -46,6 +53,11 @@ class VtkPipeline: filter: vtkAlgorithm | None = None actor: vtkActor = field(default_factory=vtkActor) highlightActor: vtkActor = field(default_factory=vtkActor) + hoverHighlightActor: vtkActor = field(default_factory=vtkActor) + hoverHighlightMapper: vtkDataSetMapper = field(default_factory=vtkDataSetMapper) + selectionNode: vtkSelectionNode = field(default_factory=vtkSelectionNode) + selection: vtkSelection = field(default_factory=vtkSelection) + extractSelection: vtkExtractSelection = field(default_factory=vtkExtractSelection) blockDataSets: list[vtkDataObject | None] = field(default_factory=list) blockGeodeIds: list[str] = field(default_factory=list) activeHighlightIds: list[int] = field(default_factory=list) From 7e0e5fe5bc1eb73ed6f0c01e0ffb754f9dc8de91 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Wed, 13 May 2026 16:35:35 +0200 Subject: [PATCH 02/18] refacto ? --- .../object/object_methods.py | 4 +- .../rpc/viewer/viewer_protocols.py | 35 ++--------------- src/opengeodeweb_viewer/vtk_protocol.py | 39 ++++++++++++++++++- 3 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index 2106deff..64892c3b 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -4,6 +4,7 @@ # Third party imports from vtkmodules.vtkIOXML import vtkXMLDataReader, vtkXMLImageDataReader from vtkmodules.vtkCommonExecutionModel import vtkAlgorithm +from vtkmodules.vtkCommonCore import vtkIdTypeArray from vtkmodules.vtkRenderingCore import ( vtkMapper, vtkActor, @@ -15,6 +16,7 @@ from vtkmodules.vtkCommonDataModel import ( vtkDataObject, vtkDataSet, + vtkSelectionNode, ) # Local application imports @@ -181,7 +183,7 @@ def highlight( actor.SetMapper(mapper) actor.VisibilityOff() - def HoverHighlight( + def setupHoverHighlight( self, actor: vtkActor, mapper: vtkDataSetMapper, input_dataset: vtkDataObject ) -> None: mapper.ScalarVisibilityOff() diff --git a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py index bc51ddfc..3f405f01 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -313,9 +313,7 @@ def setHoverHighlight(self, rpc_params: RpcParams) -> None: picker = vtkCellPicker(tolerance=0.005) picker.Pick(params.x, params.y, 0, renderer) actor = picker.GetActor() - for data_id in params.ids: - pipeline = self.get_vtk_pipeline(data_id) - pipeline.hoverHighlightActor.VisibilityOff() + self.clearHoverHighlights(params.ids) if actor: for data_id in params.ids: pipeline = self.get_vtk_pipeline(data_id) @@ -329,36 +327,9 @@ def setHoverHighlight(self, rpc_params: RpcParams) -> None: else point_id ) if id_to_select != -1: - node = pipeline.selectionNode - node.SetContentType(vtkSelectionNode.INDICES) - if params.field_type == schemas.FieldType.CELL: - node.SetFieldType(vtkSelectionNode.CELL) - else: - node.SetFieldType(vtkSelectionNode.POINT) - - selection_list = vtkIdTypeArray() - selection_list.SetNumberOfComponents(1) - selection_list.InsertNextValue(id_to_select) - node.SetSelectionList(selection_list) - - selection = pipeline.selection - if selection.GetNumberOfNodes() == 0: - selection.AddNode(node) - - extract = pipeline.extractSelection - input_port = ( - pipeline.filter.GetOutputPort() - if pipeline.filter - else pipeline.reader.GetOutputPort() + self.updateHoverHighlight( + pipeline, id_to_select, params.field_type.value ) - extract.SetInputConnection(0, input_port) - extract.SetInputData(1, selection) - extract.Update() - - pipeline.hoverHighlightMapper.SetInputConnection( - extract.GetOutputPort() - ) - pipeline.hoverHighlightActor.VisibilityOn() break self.render(-1) diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index 01c8dc8f..080951a8 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -27,7 +27,7 @@ vtkSelectionNode, ) from vtkmodules.vtkFiltersExtraction import vtkExtractSelection -from vtkmodules.vtkCommonCore import vtkStringArray +from vtkmodules.vtkCommonCore import vtkStringArray, vtkIdTypeArray from vtkmodules.vtkRenderingAnnotation import vtkCubeAxesActor, vtkAxesActor from vtkmodules.vtkInteractionWidgets import vtkOrientationMarkerWidget @@ -150,6 +150,43 @@ def reset_camera_clipping_range(self) -> None: else: renderer.ResetCameraClippingRange() + def updateHoverHighlight( + self, pipeline: VtkPipeline, id_to_select: int, field_type: str + ) -> None: + node = pipeline.selectionNode + node.SetContentType(vtkSelectionNode.INDICES) + if field_type == "CELL": + node.SetFieldType(vtkSelectionNode.CELL) + else: + node.SetFieldType(vtkSelectionNode.POINT) + + selection_list = vtkIdTypeArray() + selection_list.SetNumberOfComponents(1) + selection_list.InsertNextValue(id_to_select) + node.SetSelectionList(selection_list) + + selection = pipeline.selection + if selection.GetNumberOfNodes() == 0: + selection.AddNode(node) + + extract = pipeline.extractSelection + input_port = ( + pipeline.filter.GetOutputPort() + if pipeline.filter + else pipeline.reader.GetOutputPort() + ) + extract.SetInputConnection(0, input_port) + extract.SetInputData(1, selection) + extract.Update() + + pipeline.hoverHighlightMapper.SetInputConnection(extract.GetOutputPort()) + pipeline.hoverHighlightActor.VisibilityOn() + + def clearHoverHighlights(self, ids: list[str]) -> None: + for data_id in ids: + pipeline = self.get_vtk_pipeline(data_id) + pipeline.hoverHighlightActor.VisibilityOff() + def update_grid_scale_and_clipping_range(self) -> None: grid_scale = self.get_grid_scale() if grid_scale is not None: From b144623a4299f62b0233055e1eddcd384a294763 Mon Sep 17 00:00:00 2001 From: MaxNumerique <144453705+MaxNumerique@users.noreply.github.com> Date: Wed, 13 May 2026 14:40:35 +0000 Subject: [PATCH 03/18] Apply prepare changes --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 74d61ff7..7819587c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -61,4 +61,3 @@ wslink==1.12.4 yarl>=1 # via aiohttp -opengeodeweb-microservice==1.*,>=1.1.3 From c3853af13c314414148c2b7c876beda8184d26d7 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Wed, 13 May 2026 16:49:14 +0200 Subject: [PATCH 04/18] refacto --- .../object/object_methods.py | 15 ++++++++--- .../rpc/mesh/mesh_protocols.py | 6 +---- .../rpc/model/model_protocols.py | 4 +-- src/opengeodeweb_viewer/vtk_protocol.py | 25 ++++--------------- 4 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index 64892c3b..8d253aa9 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -183,9 +183,9 @@ def highlight( actor.SetMapper(mapper) actor.VisibilityOff() - def setupHoverHighlight( - self, actor: vtkActor, mapper: vtkDataSetMapper, input_dataset: vtkDataObject - ) -> None: + def setupHoverHighlight(self, pipeline: VtkPipeline) -> None: + actor = pipeline.hoverHighlightActor + mapper = pipeline.hoverHighlightMapper mapper.ScalarVisibilityOff() mapper.SetResolveCoincidentTopologyToPolygonOffset() prop = actor.GetProperty() @@ -198,3 +198,12 @@ def setupHoverHighlight( prop.SetEdgeColor(1, 0.5, 0) actor.SetMapper(mapper) actor.VisibilityOff() + input_port = ( + pipeline.filter.GetOutputPort() + if pipeline.filter + else pipeline.reader.GetOutputPort() + ) + pipeline.selection.AddNode(pipeline.selectionNode) + pipeline.extractSelection.SetInputConnection(0, input_port) + pipeline.extractSelection.SetInputData(1, pipeline.selection) + mapper.SetInputConnection(pipeline.extractSelection.GetOutputPort()) diff --git a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py index 5b6f8e4e..c754ca65 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py @@ -55,11 +55,7 @@ def registerMesh(self, rpc_params: RpcParams) -> None: self.highlight( data.highlightActor, data.highlightMapper, reader.GetOutputDataObject(0) ) - self.HoverHighlight( - data.hoverHighlightActor, - data.hoverHighlightMapper, - reader.GetOutputDataObject(0), - ) + self.setupHoverHighlight(data) self.registerObject(data_id, file_name, data) except Exception as e: print(f"Error registering mesh {data_id}: {str(e)}", flush=True) diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index 2c0114f8..efbc2ce0 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -124,9 +124,7 @@ def registerModel(self, rpc_params: RpcParams) -> None: ) data = VtkPipeline(reader, highlight_mapper, mapper, filter) self.highlight(data.highlightActor, data.highlightMapper, geometry_output) - self.HoverHighlight( - data.hoverHighlightActor, data.hoverHighlightMapper, geometry_output - ) + self.setupHoverHighlight(data) iterator = geometry_output.NewTreeIterator() iterator.InitTraversal() while not iterator.IsDoneWithTraversal(): diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index 080951a8..20ec126e 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -155,31 +155,16 @@ def updateHoverHighlight( ) -> None: node = pipeline.selectionNode node.SetContentType(vtkSelectionNode.INDICES) - if field_type == "CELL": - node.SetFieldType(vtkSelectionNode.CELL) - else: - node.SetFieldType(vtkSelectionNode.POINT) - + node.SetFieldType( + vtkSelectionNode.CELL if field_type == "CELL" else vtkSelectionNode.POINT + ) selection_list = vtkIdTypeArray() selection_list.SetNumberOfComponents(1) selection_list.InsertNextValue(id_to_select) node.SetSelectionList(selection_list) - selection = pipeline.selection - if selection.GetNumberOfNodes() == 0: - selection.AddNode(node) - - extract = pipeline.extractSelection - input_port = ( - pipeline.filter.GetOutputPort() - if pipeline.filter - else pipeline.reader.GetOutputPort() - ) - extract.SetInputConnection(0, input_port) - extract.SetInputData(1, selection) - extract.Update() - - pipeline.hoverHighlightMapper.SetInputConnection(extract.GetOutputPort()) + pipeline.extractSelection.Modified() + pipeline.extractSelection.Update() pipeline.hoverHighlightActor.VisibilityOn() def clearHoverHighlights(self, ids: list[str]) -> None: From 17b16b7acef2bddf84bbe96527986df8f6710c91 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Fri, 15 May 2026 14:47:37 +0200 Subject: [PATCH 05/18] models --- .../rpc/viewer/viewer_protocols.py | 36 +++++++++++-------- src/opengeodeweb_viewer/vtk_protocol.py | 10 ++++-- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py index 3f405f01..e3bfbddf 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -317,20 +317,28 @@ def setHoverHighlight(self, rpc_params: RpcParams) -> None: if actor: for data_id in params.ids: pipeline = self.get_vtk_pipeline(data_id) - if pipeline.actor == actor: - cell_id = picker.GetCellId() - point_id = picker.GetPointId() - - id_to_select = ( - cell_id - if params.field_type == schemas.FieldType.CELL - else point_id - ) - if id_to_select != -1: - self.updateHoverHighlight( - pipeline, id_to_select, params.field_type.value - ) - break + if pipeline.actor != actor: + continue + cell_id = picker.GetCellId() + point_id = picker.GetPointId() + id_to_select = ( + cell_id + if params.field_type == schemas.FieldType.CELL + else point_id + ) + if id_to_select == -1: + break + dataset = None + if isinstance(pipeline.mapper, vtkCompositePolyDataMapper): + flat_index = picker.GetFlatBlockIndex() + if 0 <= flat_index < len(pipeline.blockDataSets): + block = pipeline.blockDataSets[flat_index] + if isinstance(block, vtkDataSet): + dataset = block + self.updateHoverHighlight( + pipeline, id_to_select, params.field_type.value, dataset + ) + break self.render(-1) @exportRpc(viewer_prefix + viewer_schemas_dict["set_z_scaling"]["rpc"]) diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index 20ec126e..a0ac2a0f 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -22,6 +22,7 @@ ) from vtkmodules.vtkCommonDataModel import ( vtkDataObject, + vtkDataSet, vtkBoundingBox, vtkSelection, vtkSelectionNode, @@ -151,7 +152,11 @@ def reset_camera_clipping_range(self) -> None: renderer.ResetCameraClippingRange() def updateHoverHighlight( - self, pipeline: VtkPipeline, id_to_select: int, field_type: str + self, + pipeline: VtkPipeline, + id_to_select: int, + field_type: str, + dataset: vtkDataSet | None = None, ) -> None: node = pipeline.selectionNode node.SetContentType(vtkSelectionNode.INDICES) @@ -162,7 +167,8 @@ def updateHoverHighlight( selection_list.SetNumberOfComponents(1) selection_list.InsertNextValue(id_to_select) node.SetSelectionList(selection_list) - + if dataset is not None: + pipeline.extractSelection.SetInputData(0, dataset) pipeline.extractSelection.Modified() pipeline.extractSelection.Update() pipeline.hoverHighlightActor.VisibilityOn() From 928e8106b156a10e10fd1badf12690fd9b152d94 Mon Sep 17 00:00:00 2001 From: MaxNumerique <144453705+MaxNumerique@users.noreply.github.com> Date: Fri, 15 May 2026 12:48:13 +0000 Subject: [PATCH 06/18] Apply prepare changes --- src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py index e3bfbddf..42e3ecf8 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -322,9 +322,7 @@ def setHoverHighlight(self, rpc_params: RpcParams) -> None: cell_id = picker.GetCellId() point_id = picker.GetPointId() id_to_select = ( - cell_id - if params.field_type == schemas.FieldType.CELL - else point_id + cell_id if params.field_type == schemas.FieldType.CELL else point_id ) if id_to_select == -1: break From 6c0611df19406442d40e32e365c143a4a1bc62bd Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Fri, 15 May 2026 14:51:50 +0200 Subject: [PATCH 07/18] refacto --- .../rpc/viewer/viewer_protocols.py | 41 ++++++++----------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py index e3bfbddf..49b82686 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -309,36 +309,27 @@ def setHoverHighlight(self, rpc_params: RpcParams) -> None: rpc_params, self.viewer_schemas_dict["hover_highlight"], self.viewer_prefix ) params = schemas.HoverHighlight.from_dict(rpc_params) - renderer = self.get_renderer() picker = vtkCellPicker(tolerance=0.005) - picker.Pick(params.x, params.y, 0, renderer) - actor = picker.GetActor() + picker.Pick(params.x, params.y, 0, self.get_renderer()) self.clearHoverHighlights(params.ids) - if actor: - for data_id in params.ids: - pipeline = self.get_vtk_pipeline(data_id) - if pipeline.actor != actor: - continue - cell_id = picker.GetCellId() - point_id = picker.GetPointId() - id_to_select = ( - cell_id - if params.field_type == schemas.FieldType.CELL - else point_id - ) - if id_to_select == -1: - break + actor = picker.GetActor() + pipeline = next( + (self.get_vtk_pipeline(id) for id in params.ids if self.get_vtk_pipeline(id).actor == actor), + None, + ) + if pipeline: + id_to_select = ( + picker.GetCellId() + if params.field_type == schemas.FieldType.CELL + else picker.GetPointId() + ) + if id_to_select != -1: dataset = None if isinstance(pipeline.mapper, vtkCompositePolyDataMapper): flat_index = picker.GetFlatBlockIndex() - if 0 <= flat_index < len(pipeline.blockDataSets): - block = pipeline.blockDataSets[flat_index] - if isinstance(block, vtkDataSet): - dataset = block - self.updateHoverHighlight( - pipeline, id_to_select, params.field_type.value, dataset - ) - break + block = pipeline.blockDataSets[flat_index] if 0 <= flat_index < len(pipeline.blockDataSets) else None + dataset = block if isinstance(block, vtkDataSet) else None + self.updateHoverHighlight(pipeline, id_to_select, params.field_type.value, dataset) self.render(-1) @exportRpc(viewer_prefix + viewer_schemas_dict["set_z_scaling"]["rpc"]) From 15b6493d51d91b819808a425be16d58970907033 Mon Sep 17 00:00:00 2001 From: MaxNumerique <144453705+MaxNumerique@users.noreply.github.com> Date: Fri, 15 May 2026 12:53:23 +0000 Subject: [PATCH 08/18] Apply prepare changes --- .../rpc/viewer/viewer_protocols.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py index 49b82686..bfc76454 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -314,7 +314,11 @@ def setHoverHighlight(self, rpc_params: RpcParams) -> None: self.clearHoverHighlights(params.ids) actor = picker.GetActor() pipeline = next( - (self.get_vtk_pipeline(id) for id in params.ids if self.get_vtk_pipeline(id).actor == actor), + ( + self.get_vtk_pipeline(id) + for id in params.ids + if self.get_vtk_pipeline(id).actor == actor + ), None, ) if pipeline: @@ -327,9 +331,15 @@ def setHoverHighlight(self, rpc_params: RpcParams) -> None: dataset = None if isinstance(pipeline.mapper, vtkCompositePolyDataMapper): flat_index = picker.GetFlatBlockIndex() - block = pipeline.blockDataSets[flat_index] if 0 <= flat_index < len(pipeline.blockDataSets) else None + block = ( + pipeline.blockDataSets[flat_index] + if 0 <= flat_index < len(pipeline.blockDataSets) + else None + ) dataset = block if isinstance(block, vtkDataSet) else None - self.updateHoverHighlight(pipeline, id_to_select, params.field_type.value, dataset) + self.updateHoverHighlight( + pipeline, id_to_select, params.field_type.value, dataset + ) self.render(-1) @exportRpc(viewer_prefix + viewer_schemas_dict["set_z_scaling"]["rpc"]) From 4154e71e2a3301abb1c492d024e1d71f08ff75d7 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Fri, 15 May 2026 15:35:40 +0200 Subject: [PATCH 09/18] color green --- src/opengeodeweb_viewer/object/object_methods.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index 8d253aa9..6e719614 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -189,13 +189,13 @@ def setupHoverHighlight(self, pipeline: VtkPipeline) -> None: mapper.ScalarVisibilityOff() mapper.SetResolveCoincidentTopologyToPolygonOffset() prop = actor.GetProperty() - prop.SetColor(1, 0.5, 0) + prop.SetColor(0.235, 0.6, 0.514) prop.SetLineWidth(5) prop.SetPointSize(16) prop.SetRenderPointsAsSpheres(True) prop.SetLighting(False) prop.SetEdgeVisibility(True) - prop.SetEdgeColor(1, 0.5, 0) + prop.SetEdgeColor(0.12, 0.35, 0.30) actor.SetMapper(mapper) actor.VisibilityOff() input_port = ( From 3ad5f458a2002b7ed3482f570051357371baa092 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Fri, 15 May 2026 15:49:44 +0200 Subject: [PATCH 10/18] SetRelativeCoincidentTopologyPolygonOffsetParameters for both highlights --- src/opengeodeweb_viewer/object/object_methods.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index 6e719614..f918afac 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -172,6 +172,7 @@ def highlight( mapper.SetInputDataObject(input_dataset) mapper.ScalarVisibilityOff() mapper.SetResolveCoincidentTopologyToPolygonOffset() + mapper.SetRelativeCoincidentTopologyPolygonOffsetParameters(-2, -2) prop = actor.GetProperty() prop.SetColor(0.235, 0.6, 0.514) prop.SetLineWidth(3) @@ -188,6 +189,7 @@ def setupHoverHighlight(self, pipeline: VtkPipeline) -> None: mapper = pipeline.hoverHighlightMapper mapper.ScalarVisibilityOff() mapper.SetResolveCoincidentTopologyToPolygonOffset() + mapper.SetRelativeCoincidentTopologyPolygonOffsetParameters(-2, -2) prop = actor.GetProperty() prop.SetColor(0.235, 0.6, 0.514) prop.SetLineWidth(5) From 848e3a32ac0da2a69083e4692c72d6602fdca492 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Fri, 15 May 2026 17:54:43 +0200 Subject: [PATCH 11/18] temp --- .../object/object_methods.py | 75 +++++++++++-------- .../rpc/mesh/mesh_protocols.py | 9 +-- .../rpc/model/model_protocols.py | 40 ++++------ src/opengeodeweb_viewer/vtk_protocol.py | 31 ++++---- 4 files changed, 77 insertions(+), 78 deletions(-) diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index f918afac..98c41eb7 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -4,20 +4,18 @@ # Third party imports from vtkmodules.vtkIOXML import vtkXMLDataReader, vtkXMLImageDataReader from vtkmodules.vtkCommonExecutionModel import vtkAlgorithm -from vtkmodules.vtkCommonCore import vtkIdTypeArray from vtkmodules.vtkRenderingCore import ( vtkMapper, vtkActor, vtkTexture, - vtkCompositePolyDataMapper, - vtkCompositeDataDisplayAttributes, vtkDataSetMapper, ) from vtkmodules.vtkCommonDataModel import ( - vtkDataObject, vtkDataSet, vtkSelectionNode, + vtkSelection, ) +from vtkmodules.vtkFiltersExtraction import vtkExtractSelection # Local application imports from opengeodeweb_viewer.vtk_protocol import VtkView, VtkPipeline @@ -49,8 +47,8 @@ def registerObject( if actor.visibility == True: resetCamara = False renderer.AddActor(data.actor) - renderer.AddActor(data.highlightActor) - renderer.AddActor(data.hoverHighlightActor) + renderer.AddActor(data.highlight.actor) + renderer.AddActor(data.hoverHighlight.actor) if resetCamara: renderer.ResetCamera() @@ -59,8 +57,8 @@ def deregisterObject(self, data_id: str) -> None: renderWindow = self.getView("-1") renderer = renderWindow.GetRenderers().GetFirstRenderer() renderer.RemoveActor(pipeline.actor) - renderer.RemoveActor(pipeline.highlightActor) - renderer.RemoveActor(pipeline.hoverHighlightActor) + renderer.RemoveActor(pipeline.highlight.actor) + renderer.RemoveActor(pipeline.hoverHighlight.actor) self.deregister_object(data_id) def SetVisibility(self, data_id: str, visibility: bool) -> None: @@ -166,27 +164,15 @@ def clearColors(self, data_id: str) -> None: output.GetCellData().SetActiveScalars("") mapper.ScalarVisibilityOff() - def highlight( - self, actor: vtkActor, mapper: vtkMapper, input_dataset: vtkDataObject + def _setupHighlightPipeline( + self, + actor: vtkActor, + mapper: vtkMapper, + selection_node: vtkSelectionNode, + selection: vtkSelection, + extract_selection: vtkExtractSelection, + input_port: vtkAlgorithm, ) -> None: - mapper.SetInputDataObject(input_dataset) - mapper.ScalarVisibilityOff() - mapper.SetResolveCoincidentTopologyToPolygonOffset() - mapper.SetRelativeCoincidentTopologyPolygonOffsetParameters(-2, -2) - prop = actor.GetProperty() - prop.SetColor(0.235, 0.6, 0.514) - prop.SetLineWidth(3) - prop.SetPointSize(14) - prop.SetRenderPointsAsSpheres(True) - prop.SetLighting(True) - prop.SetEdgeVisibility(True) - prop.SetEdgeColor(0.12, 0.35, 0.30) - actor.SetMapper(mapper) - actor.VisibilityOff() - - def setupHoverHighlight(self, pipeline: VtkPipeline) -> None: - actor = pipeline.hoverHighlightActor - mapper = pipeline.hoverHighlightMapper mapper.ScalarVisibilityOff() mapper.SetResolveCoincidentTopologyToPolygonOffset() mapper.SetRelativeCoincidentTopologyPolygonOffsetParameters(-2, -2) @@ -198,14 +184,39 @@ def setupHoverHighlight(self, pipeline: VtkPipeline) -> None: prop.SetLighting(False) prop.SetEdgeVisibility(True) prop.SetEdgeColor(0.12, 0.35, 0.30) + selection.AddNode(selection_node) + extract_selection.SetInputConnection(0, input_port) + extract_selection.SetInputData(1, selection) + mapper.SetInputConnection(extract_selection.GetOutputPort()) actor.SetMapper(mapper) actor.VisibilityOff() + + def setupHighlight(self, pipeline: VtkPipeline) -> None: input_port = ( pipeline.filter.GetOutputPort() if pipeline.filter else pipeline.reader.GetOutputPort() ) - pipeline.selection.AddNode(pipeline.selectionNode) - pipeline.extractSelection.SetInputConnection(0, input_port) - pipeline.extractSelection.SetInputData(1, pipeline.selection) - mapper.SetInputConnection(pipeline.extractSelection.GetOutputPort()) + self._setupHighlightPipeline( + pipeline.highlight.actor, + pipeline.highlight.mapper, + pipeline.highlight.selectionNode, + pipeline.highlight.selection, + pipeline.highlight.extractSelection, + input_port, + ) + + def setupHoverHighlight(self, pipeline: VtkPipeline) -> None: + input_port = ( + pipeline.filter.GetOutputPort() + if pipeline.filter + else pipeline.reader.GetOutputPort() + ) + self._setupHighlightPipeline( + pipeline.hoverHighlight.actor, + pipeline.hoverHighlight.mapper, + pipeline.hoverHighlight.selectionNode, + pipeline.hoverHighlight.selection, + pipeline.hoverHighlight.extractSelection, + input_port, + ) diff --git a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py index c754ca65..8f54dbad 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py @@ -50,11 +50,8 @@ def registerMesh(self, rpc_params: RpcParams) -> None: reader.Update() mapper = vtkDataSetMapper() mapper.SetInputConnection(reader.GetOutputPort()) - highlight_mapper = vtkDataSetMapper() - data = VtkPipeline(reader, highlight_mapper, mapper) - self.highlight( - data.highlightActor, data.highlightMapper, reader.GetOutputDataObject(0) - ) + data = VtkPipeline(reader, mapper) + self.setupHighlight(data) self.setupHoverHighlight(data) self.registerObject(data_id, file_name, data) except Exception as e: @@ -178,5 +175,5 @@ def setMeshhighlight(self, rpc_params: RpcParams) -> None: ) params = schemas.Highlight.from_dict(rpc_params) pipeline = self.get_vtk_pipeline(params.id) - pipeline.highlightActor.SetVisibility(params.visibility) + pipeline.highlight.actor.SetVisibility(params.visibility) self.render(-1) diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index 508860e1..efe2f644 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -6,11 +6,13 @@ vtkCompositeDataSet, vtkBoundingBox, vtkDataSet, + vtkSelectionNode, ) from vtkmodules.vtkRenderingCore import ( - vtkCompositeDataDisplayAttributes, vtkCompositePolyDataMapper, + vtkCompositeDataDisplayAttributes, ) +from vtkmodules.vtkCommonCore import vtkIdTypeArray from vtkmodules.vtkIOXML import vtkXMLMultiBlockDataReader from vtkmodules.vtkFiltersGeometry import vtkGeometryFilter from wslink import register as exportRpc # type: ignore @@ -120,12 +122,8 @@ def registerModel(self, rpc_params: RpcParams) -> None: mapper.SetInputDataObject(geometry_output) attributes = vtkCompositeDataDisplayAttributes() mapper.SetCompositeDataDisplayAttributes(attributes) - highlight_mapper = vtkCompositePolyDataMapper() - highlight_mapper.SetCompositeDataDisplayAttributes( - vtkCompositeDataDisplayAttributes() - ) - data = VtkPipeline(reader, highlight_mapper, mapper, filter) - self.highlight(data.highlightActor, data.highlightMapper, geometry_output) + data = VtkPipeline(reader, mapper, filter) + self.setupHighlight(data) self.setupHoverHighlight(data) iterator = geometry_output.NewTreeIterator() iterator.InitTraversal() @@ -137,9 +135,6 @@ def registerModel(self, rpc_params: RpcParams) -> None: data.blockDataSets.append(None) data.blockGeodeIds.append("") data.blockDataSets.append(block) - highlight_mapper.GetCompositeDataDisplayAttributes().SetBlockVisibility( - block, False - ) meta = iterator.GetCurrentMetaData() name = meta.Get(vtkCompositeDataSet.NAME()) data.blockGeodeIds.append(name) @@ -172,23 +167,16 @@ def setModelhighlight(self, rpc_params: RpcParams) -> None: ) params = schemas.Highlight.from_dict(rpc_params) pipeline = self.get_vtk_pipeline(params.id) - pipeline.highlightActor.SetVisibility(params.visibility) - mapper = pipeline.highlightMapper - assert isinstance(mapper, vtkCompositePolyDataMapper) - attributes = mapper.GetCompositeDataDisplayAttributes() - - for i in pipeline.activeHighlightIds: - attributes.SetBlockVisibility(pipeline.blockDataSets[i], False) - - pipeline.activeHighlightIds = [] + pipeline.highlight.actor.SetVisibility(params.visibility) + selection_node = pipeline.highlight.selectionNode + selection_node.Initialize() + ids = vtkIdTypeArray() if params.visibility: - pipeline.activeHighlightIds = [ - i for i in params.block_ids if pipeline.blockDataSets[i] - ] - for i in pipeline.activeHighlightIds: - attributes.SetBlockVisibility(pipeline.blockDataSets[i], True) - - mapper.Modified() + for block_id in params.block_ids: + ids.InsertNextValue(block_id) + selection_node.SetContentType(vtkSelectionNode.BLOCKS) + selection_node.SetSelectionList(ids) + pipeline.highlight.extractSelection.Modified() self.render(-1) @exportRpc(model_prefix + model_schemas_dict["get_blocks_bounds"]["rpc"]) diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index a0ac2a0f..7b4d7424 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -46,22 +46,25 @@ class ViewerData: viewer_elements_type: ViewerElementsType +@dataclass +class HighlightPipeline: + actor: vtkActor = field(default_factory=vtkActor) + mapper: vtkDataSetMapper = field(default_factory=vtkDataSetMapper) + selectionNode: vtkSelectionNode = field(default_factory=vtkSelectionNode) + selection: vtkSelection = field(default_factory=vtkSelection) + extractSelection: vtkExtractSelection = field(default_factory=vtkExtractSelection) + + @dataclass class VtkPipeline: reader: vtkXMLReader - highlightMapper: vtkMapper mapper: vtkMapper filter: vtkAlgorithm | None = None actor: vtkActor = field(default_factory=vtkActor) - highlightActor: vtkActor = field(default_factory=vtkActor) - hoverHighlightActor: vtkActor = field(default_factory=vtkActor) - hoverHighlightMapper: vtkDataSetMapper = field(default_factory=vtkDataSetMapper) - selectionNode: vtkSelectionNode = field(default_factory=vtkSelectionNode) - selection: vtkSelection = field(default_factory=vtkSelection) - extractSelection: vtkExtractSelection = field(default_factory=vtkExtractSelection) + highlight: HighlightPipeline = field(default_factory=HighlightPipeline) + hoverHighlight: HighlightPipeline = field(default_factory=HighlightPipeline) blockDataSets: list[vtkDataObject | None] = field(default_factory=list) blockGeodeIds: list[str] = field(default_factory=list) - activeHighlightIds: list[int] = field(default_factory=list) class VtkTypingMixin: @@ -158,7 +161,7 @@ def updateHoverHighlight( field_type: str, dataset: vtkDataSet | None = None, ) -> None: - node = pipeline.selectionNode + node = pipeline.hoverHighlight.selectionNode node.SetContentType(vtkSelectionNode.INDICES) node.SetFieldType( vtkSelectionNode.CELL if field_type == "CELL" else vtkSelectionNode.POINT @@ -168,15 +171,15 @@ def updateHoverHighlight( selection_list.InsertNextValue(id_to_select) node.SetSelectionList(selection_list) if dataset is not None: - pipeline.extractSelection.SetInputData(0, dataset) - pipeline.extractSelection.Modified() - pipeline.extractSelection.Update() - pipeline.hoverHighlightActor.VisibilityOn() + pipeline.hoverHighlight.extractSelection.SetInputData(0, dataset) + pipeline.hoverHighlight.extractSelection.Modified() + pipeline.hoverHighlight.extractSelection.Update() + pipeline.hoverHighlight.actor.VisibilityOn() def clearHoverHighlights(self, ids: list[str]) -> None: for data_id in ids: pipeline = self.get_vtk_pipeline(data_id) - pipeline.hoverHighlightActor.VisibilityOff() + pipeline.hoverHighlight.actor.VisibilityOff() def update_grid_scale_and_clipping_range(self) -> None: grid_scale = self.get_grid_scale() From 19227c507c8b29d4159c0e7caf76f9ab45694684 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Fri, 15 May 2026 18:58:48 +0200 Subject: [PATCH 12/18] harmonize logic between highlights methods --- .../object/object_methods.py | 39 +++++---------- .../rpc/mesh/mesh_protocols.py | 17 ++++--- .../rpc/model/model_protocols.py | 47 ++++++++----------- src/opengeodeweb_viewer/vtk_protocol.py | 4 -- 4 files changed, 42 insertions(+), 65 deletions(-) diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index f918afac..9ba98664 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -14,9 +14,7 @@ vtkDataSetMapper, ) from vtkmodules.vtkCommonDataModel import ( - vtkDataObject, vtkDataSet, - vtkSelectionNode, ) # Local application imports @@ -49,7 +47,6 @@ def registerObject( if actor.visibility == True: resetCamara = False renderer.AddActor(data.actor) - renderer.AddActor(data.highlightActor) renderer.AddActor(data.hoverHighlightActor) if resetCamara: renderer.ResetCamera() @@ -59,7 +56,6 @@ def deregisterObject(self, data_id: str) -> None: renderWindow = self.getView("-1") renderer = renderWindow.GetRenderers().GetFirstRenderer() renderer.RemoveActor(pipeline.actor) - renderer.RemoveActor(pipeline.highlightActor) renderer.RemoveActor(pipeline.hoverHighlightActor) self.deregister_object(data_id) @@ -166,40 +162,27 @@ def clearColors(self, data_id: str) -> None: output.GetCellData().SetActiveScalars("") mapper.ScalarVisibilityOff() - def highlight( - self, actor: vtkActor, mapper: vtkMapper, input_dataset: vtkDataObject + def _apply_highlight_style( + self, actor: vtkActor, mapper: vtkDataSetMapper ) -> None: - mapper.SetInputDataObject(input_dataset) mapper.ScalarVisibilityOff() mapper.SetResolveCoincidentTopologyToPolygonOffset() mapper.SetRelativeCoincidentTopologyPolygonOffsetParameters(-2, -2) prop = actor.GetProperty() prop.SetColor(0.235, 0.6, 0.514) - prop.SetLineWidth(3) - prop.SetPointSize(14) - prop.SetRenderPointsAsSpheres(True) - prop.SetLighting(True) - prop.SetEdgeVisibility(True) - prop.SetEdgeColor(0.12, 0.35, 0.30) - actor.SetMapper(mapper) - actor.VisibilityOff() - - def setupHoverHighlight(self, pipeline: VtkPipeline) -> None: - actor = pipeline.hoverHighlightActor - mapper = pipeline.hoverHighlightMapper - mapper.ScalarVisibilityOff() - mapper.SetResolveCoincidentTopologyToPolygonOffset() - mapper.SetRelativeCoincidentTopologyPolygonOffsetParameters(-2, -2) - prop = actor.GetProperty() - prop.SetColor(0.235, 0.6, 0.514) - prop.SetLineWidth(5) - prop.SetPointSize(16) + prop.SetLineWidth(4) + prop.SetPointSize(15) prop.SetRenderPointsAsSpheres(True) prop.SetLighting(False) prop.SetEdgeVisibility(True) prop.SetEdgeColor(0.12, 0.35, 0.30) actor.SetMapper(mapper) actor.VisibilityOff() + + def setupHighlight(self, pipeline: VtkPipeline) -> None: + self._apply_highlight_style( + pipeline.hoverHighlightActor, pipeline.hoverHighlightMapper + ) input_port = ( pipeline.filter.GetOutputPort() if pipeline.filter @@ -208,4 +191,6 @@ def setupHoverHighlight(self, pipeline: VtkPipeline) -> None: pipeline.selection.AddNode(pipeline.selectionNode) pipeline.extractSelection.SetInputConnection(0, input_port) pipeline.extractSelection.SetInputData(1, pipeline.selection) - mapper.SetInputConnection(pipeline.extractSelection.GetOutputPort()) + pipeline.hoverHighlightMapper.SetInputConnection( + pipeline.extractSelection.GetOutputPort() + ) diff --git a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py index c754ca65..40206931 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py @@ -50,12 +50,8 @@ def registerMesh(self, rpc_params: RpcParams) -> None: reader.Update() mapper = vtkDataSetMapper() mapper.SetInputConnection(reader.GetOutputPort()) - highlight_mapper = vtkDataSetMapper() - data = VtkPipeline(reader, highlight_mapper, mapper) - self.highlight( - data.highlightActor, data.highlightMapper, reader.GetOutputDataObject(0) - ) - self.setupHoverHighlight(data) + data = VtkPipeline(reader, mapper) + self.setupHighlight(data) self.registerObject(data_id, file_name, data) except Exception as e: print(f"Error registering mesh {data_id}: {str(e)}", flush=True) @@ -178,5 +174,12 @@ def setMeshhighlight(self, rpc_params: RpcParams) -> None: ) params = schemas.Highlight.from_dict(rpc_params) pipeline = self.get_vtk_pipeline(params.id) - pipeline.highlightActor.SetVisibility(params.visibility) + if params.visibility: + dataset = pipeline.reader.GetOutputDataObject(0) + pipeline.hoverHighlightMapper.SetInputDataObject(dataset) + else: + pipeline.hoverHighlightMapper.SetInputConnection( + pipeline.extractSelection.GetOutputPort() + ) + pipeline.hoverHighlightActor.SetVisibility(params.visibility) self.render(-1) diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index 508860e1..8fbe98f5 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -11,6 +11,7 @@ vtkCompositeDataDisplayAttributes, vtkCompositePolyDataMapper, ) +from vtkmodules.vtkFiltersCore import vtkAppendDataSets from vtkmodules.vtkIOXML import vtkXMLMultiBlockDataReader from vtkmodules.vtkFiltersGeometry import vtkGeometryFilter from wslink import register as exportRpc # type: ignore @@ -120,13 +121,8 @@ def registerModel(self, rpc_params: RpcParams) -> None: mapper.SetInputDataObject(geometry_output) attributes = vtkCompositeDataDisplayAttributes() mapper.SetCompositeDataDisplayAttributes(attributes) - highlight_mapper = vtkCompositePolyDataMapper() - highlight_mapper.SetCompositeDataDisplayAttributes( - vtkCompositeDataDisplayAttributes() - ) - data = VtkPipeline(reader, highlight_mapper, mapper, filter) - self.highlight(data.highlightActor, data.highlightMapper, geometry_output) - self.setupHoverHighlight(data) + data = VtkPipeline(reader, mapper, filter) + self.setupHighlight(data) iterator = geometry_output.NewTreeIterator() iterator.InitTraversal() while not iterator.IsDoneWithTraversal(): @@ -137,9 +133,6 @@ def registerModel(self, rpc_params: RpcParams) -> None: data.blockDataSets.append(None) data.blockGeodeIds.append("") data.blockDataSets.append(block) - highlight_mapper.GetCompositeDataDisplayAttributes().SetBlockVisibility( - block, False - ) meta = iterator.GetCurrentMetaData() name = meta.Get(vtkCompositeDataSet.NAME()) data.blockGeodeIds.append(name) @@ -172,23 +165,23 @@ def setModelhighlight(self, rpc_params: RpcParams) -> None: ) params = schemas.Highlight.from_dict(rpc_params) pipeline = self.get_vtk_pipeline(params.id) - pipeline.highlightActor.SetVisibility(params.visibility) - mapper = pipeline.highlightMapper - assert isinstance(mapper, vtkCompositePolyDataMapper) - attributes = mapper.GetCompositeDataDisplayAttributes() - - for i in pipeline.activeHighlightIds: - attributes.SetBlockVisibility(pipeline.blockDataSets[i], False) - - pipeline.activeHighlightIds = [] - if params.visibility: - pipeline.activeHighlightIds = [ - i for i in params.block_ids if pipeline.blockDataSets[i] - ] - for i in pipeline.activeHighlightIds: - attributes.SetBlockVisibility(pipeline.blockDataSets[i], True) - - mapper.Modified() + if params.visibility and params.block_ids: + append = vtkAppendDataSets() + for i in params.block_ids: + block = ( + pipeline.blockDataSets[i] + if i < len(pipeline.blockDataSets) + else None + ) + if isinstance(block, vtkDataSet): + append.AddInputData(block) + append.Update() + pipeline.hoverHighlightMapper.SetInputDataObject(append.GetOutput()) + else: + pipeline.hoverHighlightMapper.SetInputConnection( + pipeline.extractSelection.GetOutputPort() + ) + pipeline.hoverHighlightActor.SetVisibility(params.visibility) self.render(-1) @exportRpc(model_prefix + model_schemas_dict["get_blocks_bounds"]["rpc"]) diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index a0ac2a0f..81647eb0 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -17,7 +17,6 @@ vtkMapper, vtkRenderer, vtkRenderWindow, - vtkCompositePolyDataMapper, vtkDataSetMapper, ) from vtkmodules.vtkCommonDataModel import ( @@ -49,11 +48,9 @@ class ViewerData: @dataclass class VtkPipeline: reader: vtkXMLReader - highlightMapper: vtkMapper mapper: vtkMapper filter: vtkAlgorithm | None = None actor: vtkActor = field(default_factory=vtkActor) - highlightActor: vtkActor = field(default_factory=vtkActor) hoverHighlightActor: vtkActor = field(default_factory=vtkActor) hoverHighlightMapper: vtkDataSetMapper = field(default_factory=vtkDataSetMapper) selectionNode: vtkSelectionNode = field(default_factory=vtkSelectionNode) @@ -61,7 +58,6 @@ class VtkPipeline: extractSelection: vtkExtractSelection = field(default_factory=vtkExtractSelection) blockDataSets: list[vtkDataObject | None] = field(default_factory=list) blockGeodeIds: list[str] = field(default_factory=list) - activeHighlightIds: list[int] = field(default_factory=list) class VtkTypingMixin: From 3805f42541357c36bd5a08c369197c8ba2c18042 Mon Sep 17 00:00:00 2001 From: MaxNumerique <144453705+MaxNumerique@users.noreply.github.com> Date: Fri, 15 May 2026 17:00:04 +0000 Subject: [PATCH 13/18] Apply prepare changes --- src/opengeodeweb_viewer/object/object_methods.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index 5064e97b..33535e36 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -160,9 +160,7 @@ def clearColors(self, data_id: str) -> None: output.GetCellData().SetActiveScalars("") mapper.ScalarVisibilityOff() - def _apply_highlight_style( - self, actor: vtkActor, mapper: vtkDataSetMapper - ) -> None: + def _apply_highlight_style(self, actor: vtkActor, mapper: vtkDataSetMapper) -> None: mapper.ScalarVisibilityOff() mapper.SetResolveCoincidentTopologyToPolygonOffset() mapper.SetRelativeCoincidentTopologyPolygonOffsetParameters(-2, -2) From cc69beebf625ee55f15617eded0e73f275535236 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Fri, 15 May 2026 19:00:11 +0200 Subject: [PATCH 14/18] highlight over setuphighlight --- src/opengeodeweb_viewer/object/object_methods.py | 2 +- src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py | 2 +- src/opengeodeweb_viewer/rpc/model/model_protocols.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index 5064e97b..1b590727 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -181,7 +181,7 @@ def _apply_highlight_style( actor.SetMapper(mapper) actor.VisibilityOff() - def setupHighlight(self, pipeline: VtkPipeline) -> None: + def highlight(self, pipeline: VtkPipeline) -> None: self._apply_highlight_style( pipeline.hoverHighlightActor, pipeline.hoverHighlightMapper ) diff --git a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py index 40206931..18d80a69 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py @@ -51,7 +51,7 @@ def registerMesh(self, rpc_params: RpcParams) -> None: mapper = vtkDataSetMapper() mapper.SetInputConnection(reader.GetOutputPort()) data = VtkPipeline(reader, mapper) - self.setupHighlight(data) + self.highlight(data) self.registerObject(data_id, file_name, data) except Exception as e: print(f"Error registering mesh {data_id}: {str(e)}", flush=True) diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index a06793c5..b566a45c 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -123,7 +123,7 @@ def registerModel(self, rpc_params: RpcParams) -> None: attributes = vtkCompositeDataDisplayAttributes() mapper.SetCompositeDataDisplayAttributes(attributes) data = VtkPipeline(reader, mapper, filter) - self.setupHighlight(data) + self.highlight(data) iterator = geometry_output.NewTreeIterator() iterator.InitTraversal() while not iterator.IsDoneWithTraversal(): From c443493adb7b1e771f76761d6bd67a688313519e Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Fri, 15 May 2026 19:12:44 +0200 Subject: [PATCH 15/18] more refacto --- .../object/object_methods.py | 23 +++++++------------ .../rpc/mesh/mesh_protocols.py | 8 +++---- .../rpc/model/model_protocols.py | 8 +++---- src/opengeodeweb_viewer/vtk_protocol.py | 6 +---- 4 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index c239e168..d5e8f42f 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -45,7 +45,7 @@ def registerObject( if actor.visibility == True: resetCamara = False renderer.AddActor(data.actor) - renderer.AddActor(data.hoverHighlightActor) + renderer.AddActor(data.hoverHighlight.actor) if resetCamara: renderer.ResetCamera() @@ -54,7 +54,7 @@ def deregisterObject(self, data_id: str) -> None: renderWindow = self.getView("-1") renderer = renderWindow.GetRenderers().GetFirstRenderer() renderer.RemoveActor(pipeline.actor) - renderer.RemoveActor(pipeline.hoverHighlightActor) + renderer.RemoveActor(pipeline.hoverHighlight.actor) self.deregister_object(data_id) def SetVisibility(self, data_id: str, visibility: bool) -> None: @@ -172,25 +172,18 @@ def _apply_highlight_style(self, actor: vtkActor, mapper: vtkDataSetMapper) -> N prop.SetLighting(False) prop.SetEdgeVisibility(True) prop.SetEdgeColor(0.12, 0.35, 0.30) - selection.AddNode(selection_node) - extract_selection.SetInputConnection(0, input_port) - extract_selection.SetInputData(1, selection) - mapper.SetInputConnection(extract_selection.GetOutputPort()) actor.SetMapper(mapper) actor.VisibilityOff() def highlight(self, pipeline: VtkPipeline) -> None: - self._apply_highlight_style( - pipeline.hoverHighlightActor, pipeline.hoverHighlightMapper - ) + hl = pipeline.hoverHighlight + self._apply_highlight_style(hl.actor, hl.mapper) input_port = ( pipeline.filter.GetOutputPort() if pipeline.filter else pipeline.reader.GetOutputPort() ) - pipeline.selection.AddNode(pipeline.selectionNode) - pipeline.extractSelection.SetInputConnection(0, input_port) - pipeline.extractSelection.SetInputData(1, pipeline.selection) - pipeline.hoverHighlightMapper.SetInputConnection( - pipeline.extractSelection.GetOutputPort() - ) + hl.selection.AddNode(hl.selectionNode) + hl.extractSelection.SetInputConnection(0, input_port) + hl.extractSelection.SetInputData(1, hl.selection) + hl.mapper.SetInputConnection(hl.extractSelection.GetOutputPort()) diff --git a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py index 18d80a69..7bccb2f4 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py @@ -176,10 +176,10 @@ def setMeshhighlight(self, rpc_params: RpcParams) -> None: pipeline = self.get_vtk_pipeline(params.id) if params.visibility: dataset = pipeline.reader.GetOutputDataObject(0) - pipeline.hoverHighlightMapper.SetInputDataObject(dataset) + pipeline.hoverHighlight.mapper.SetInputDataObject(dataset) else: - pipeline.hoverHighlightMapper.SetInputConnection( - pipeline.extractSelection.GetOutputPort() + pipeline.hoverHighlight.mapper.SetInputConnection( + pipeline.hoverHighlight.extractSelection.GetOutputPort() ) - pipeline.hoverHighlightActor.SetVisibility(params.visibility) + pipeline.hoverHighlight.actor.SetVisibility(params.visibility) self.render(-1) diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index b566a45c..ca0a8086 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -177,12 +177,12 @@ def setModelhighlight(self, rpc_params: RpcParams) -> None: if isinstance(block, vtkDataSet): append.AddInputData(block) append.Update() - pipeline.hoverHighlightMapper.SetInputDataObject(append.GetOutput()) + pipeline.hoverHighlight.mapper.SetInputDataObject(append.GetOutput()) else: - pipeline.hoverHighlightMapper.SetInputConnection( - pipeline.extractSelection.GetOutputPort() + pipeline.hoverHighlight.mapper.SetInputConnection( + pipeline.hoverHighlight.extractSelection.GetOutputPort() ) - pipeline.hoverHighlightActor.SetVisibility(params.visibility) + pipeline.hoverHighlight.actor.SetVisibility(params.visibility) self.render(-1) @exportRpc(model_prefix + model_schemas_dict["get_blocks_bounds"]["rpc"]) diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index 030fa262..786806e8 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -60,11 +60,7 @@ class VtkPipeline: mapper: vtkMapper filter: vtkAlgorithm | None = None actor: vtkActor = field(default_factory=vtkActor) - hoverHighlightActor: vtkActor = field(default_factory=vtkActor) - hoverHighlightMapper: vtkDataSetMapper = field(default_factory=vtkDataSetMapper) - selectionNode: vtkSelectionNode = field(default_factory=vtkSelectionNode) - selection: vtkSelection = field(default_factory=vtkSelection) - extractSelection: vtkExtractSelection = field(default_factory=vtkExtractSelection) + hoverHighlight: HighlightPipeline = field(default_factory=HighlightPipeline) blockDataSets: list[vtkDataObject | None] = field(default_factory=list) blockGeodeIds: list[str] = field(default_factory=list) From 333ccf2051fd3bf81122307129327e9fa783ceab Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Fri, 15 May 2026 19:18:38 +0200 Subject: [PATCH 16/18] fix imports --- src/opengeodeweb_viewer/object/object_methods.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index d5e8f42f..470d8dda 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -8,6 +8,8 @@ vtkMapper, vtkActor, vtkTexture, + vtkCompositePolyDataMapper, + vtkCompositeDataDisplayAttributes, vtkDataSetMapper, ) from vtkmodules.vtkCommonDataModel import ( From a135988f1757563dfbfd0ced22e80dc3731ba533 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Mon, 18 May 2026 12:00:46 +0200 Subject: [PATCH 17/18] actor.SetUseBounds(False) --- src/opengeodeweb_viewer/object/object_methods.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index 470d8dda..a6fe930d 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -176,6 +176,7 @@ def _apply_highlight_style(self, actor: vtkActor, mapper: vtkDataSetMapper) -> N prop.SetEdgeColor(0.12, 0.35, 0.30) actor.SetMapper(mapper) actor.VisibilityOff() + actor.SetUseBounds(False) def highlight(self, pipeline: VtkPipeline) -> None: hl = pipeline.hoverHighlight From 2758704e0475567c7e70592e7601fac2d1e240ab Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Mon, 18 May 2026 12:08:37 +0200 Subject: [PATCH 18/18] highlight --- src/opengeodeweb_viewer/object/object_methods.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index a6fe930d..a6c27db8 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -179,14 +179,14 @@ def _apply_highlight_style(self, actor: vtkActor, mapper: vtkDataSetMapper) -> N actor.SetUseBounds(False) def highlight(self, pipeline: VtkPipeline) -> None: - hl = pipeline.hoverHighlight - self._apply_highlight_style(hl.actor, hl.mapper) + highlight = pipeline.hoverHighlight + self._apply_highlight_style(highlight.actor, highlight.mapper) input_port = ( pipeline.filter.GetOutputPort() if pipeline.filter else pipeline.reader.GetOutputPort() ) - hl.selection.AddNode(hl.selectionNode) - hl.extractSelection.SetInputConnection(0, input_port) - hl.extractSelection.SetInputData(1, hl.selection) - hl.mapper.SetInputConnection(hl.extractSelection.GetOutputPort()) + highlight.selection.AddNode(highlight.selectionNode) + highlight.extractSelection.SetInputConnection(0, input_port) + highlight.extractSelection.SetInputData(1, highlight.selection) + highlight.mapper.SetInputConnection(highlight.extractSelection.GetOutputPort())