diff --git a/commitlint.config.js b/commitlint.config.js index a397334..0c07c26 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -14,6 +14,7 @@ const Configuration = { "type-empty": [0], "type-enum": [2, "always", ["feat", "fix", "perf"]], }, -} + defaultIgnores: false, +}; -export default Configuration +export default Configuration; diff --git a/opengeodeweb_viewer_schemas.json b/opengeodeweb_viewer_schemas.json index e29f0e6..14c832d 100644 --- a/opengeodeweb_viewer_schemas.json +++ b/opengeodeweb_viewer_schemas.json @@ -1927,9 +1927,9 @@ ], "additionalProperties": false }, - "hover_highlight": { - "$id": "opengeodeweb_viewer.viewer.hover_highlight", - "rpc": "hover_highlight", + "highlight": { + "$id": "opengeodeweb_viewer.viewer.highlight", + "rpc": "highlight", "type": "object", "properties": { "x": { diff --git a/requirements.txt b/requirements.txt index 74d61ff..7819587 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 diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index a6c27db..d95dc7d 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -47,7 +47,7 @@ def registerObject( if actor.visibility == True: resetCamara = False renderer.AddActor(data.actor) - renderer.AddActor(data.hoverHighlight.actor) + renderer.AddActor(data.highlight.actor) if resetCamara: renderer.ResetCamera() @@ -56,7 +56,7 @@ def deregisterObject(self, data_id: str) -> None: renderWindow = self.getView("-1") renderer = renderWindow.GetRenderers().GetFirstRenderer() renderer.RemoveActor(pipeline.actor) - renderer.RemoveActor(pipeline.hoverHighlight.actor) + renderer.RemoveActor(pipeline.highlight.actor) self.deregister_object(data_id) def SetVisibility(self, data_id: str, visibility: bool) -> None: @@ -179,7 +179,7 @@ def _apply_highlight_style(self, actor: vtkActor, mapper: vtkDataSetMapper) -> N actor.SetUseBounds(False) def highlight(self, pipeline: VtkPipeline) -> None: - highlight = pipeline.hoverHighlight + highlight = pipeline.highlight self._apply_highlight_style(highlight.actor, highlight.mapper) input_port = ( pipeline.filter.GetOutputPort() diff --git a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py index 7bccb2f..629c40a 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.hoverHighlight.mapper.SetInputDataObject(dataset) + pipeline.highlight.mapper.SetInputDataObject(dataset) else: - pipeline.hoverHighlight.mapper.SetInputConnection( - pipeline.hoverHighlight.extractSelection.GetOutputPort() + pipeline.highlight.mapper.SetInputConnection( + pipeline.highlight.extractSelection.GetOutputPort() ) - pipeline.hoverHighlight.actor.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 ca0a808..8dec416 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.hoverHighlight.mapper.SetInputDataObject(append.GetOutput()) + pipeline.highlight.mapper.SetInputDataObject(append.GetOutput()) else: - pipeline.hoverHighlight.mapper.SetInputConnection( - pipeline.hoverHighlight.extractSelection.GetOutputPort() + pipeline.highlight.mapper.SetInputConnection( + pipeline.highlight.extractSelection.GetOutputPort() ) - pipeline.hoverHighlight.actor.SetVisibility(params.visibility) + pipeline.highlight.actor.SetVisibility(params.visibility) self.render(-1) @exportRpc(model_prefix + model_schemas_dict["get_blocks_bounds"]["rpc"]) diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py index dc64d6c..4949cd7 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py @@ -7,7 +7,7 @@ from .reset_camera import * from .render import * from .picked_ids import * -from .hover_highlight import * +from .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/highlight.json similarity index 93% rename from src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.json rename to src/opengeodeweb_viewer/rpc/viewer/schemas/highlight.json index 365cf0f..d3933a9 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.json +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/highlight.json @@ -1,5 +1,5 @@ { - "rpc": "hover_highlight", + "rpc": "highlight", "type": "object", "properties": { "x": { diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/highlight.py similarity index 89% rename from src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.py rename to src/opengeodeweb_viewer/rpc/viewer/schemas/highlight.py index f256a02..ae06e17 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.py +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/highlight.py @@ -10,7 +10,7 @@ class FieldType(Enum): @dataclass -class HoverHighlight(DataClassJsonMixin): +class Highlight(DataClassJsonMixin): def __post_init__(self) -> None: print(self, flush=True) diff --git a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py index bfc7645..3ffffab 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -303,44 +303,82 @@ 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: + @exportRpc(viewer_prefix + viewer_schemas_dict["highlight"]["rpc"]) + def setHighlight( + self, rpc_params: RpcParams + ) -> dict[str, str | int | None | dict[str, list[float] | float]]: validate_schema( - rpc_params, self.viewer_schemas_dict["hover_highlight"], self.viewer_prefix + rpc_params, self.viewer_schemas_dict["highlight"], self.viewer_prefix ) - params = schemas.HoverHighlight.from_dict(rpc_params) + params = schemas.Highlight.from_dict(rpc_params) picker = vtkCellPicker(tolerance=0.005) picker.Pick(params.x, params.y, 0, self.get_renderer()) - self.clearHoverHighlights(params.ids) + self.clear_highlights(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 - ), - None, + pipeline_id = next( + (id for id in params.ids if self.get_vtk_pipeline(id).actor == actor), None ) - if pipeline: - id_to_select = ( - picker.GetCellId() + id_to_select = ( + picker.GetCellId() + if params.field_type == schemas.FieldType.CELL + else picker.GetPointId() + ) + + if not pipeline_id or id_to_select == -1: + self.render(-1) + return {} + + pipeline = self.get_vtk_pipeline(pipeline_id) + dataset = None + geode_id = None + if isinstance(pipeline.mapper, vtkCompositePolyDataMapper): + flat_index = picker.GetFlatBlockIndex() + dataset = ( + pipeline.blockDataSets[flat_index] + if 0 <= flat_index < len(pipeline.blockDataSets) + else None + ) + geode_id = ( + pipeline.blockGeodeIds[flat_index] + if 0 <= flat_index < len(pipeline.blockGeodeIds) + else None + ) + + self.update_highlight(pipeline, id_to_select, params.field_type.value, dataset) + self.render(-1) + + data_obj = dataset or pipeline.reader.GetOutputDataObject(0) + data_attributes = {} + if isinstance(data_obj, vtkDataSet): + field_data = ( + data_obj.GetCellData() if params.field_type == schemas.FieldType.CELL - else picker.GetPointId() + else data_obj.GetPointData() ) - if id_to_select != -1: - 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 + for array_index in range(field_data.GetNumberOfArrays()): + array = field_data.GetArray(array_index) + if array and array.GetName(): + num_comps = array.GetNumberOfComponents() + component_values = [ + array.GetComponent(id_to_select, component_index) + for component_index in range(num_comps) + ] + data_attributes[array.GetName()] = ( + component_values[0] if num_comps == 1 else component_values ) - dataset = block if isinstance(block, vtkDataSet) else None - self.updateHoverHighlight( - pipeline, id_to_select, params.field_type.value, dataset - ) - self.render(-1) + + if params.field_type == schemas.FieldType.POINT: + point_coordinates = data_obj.GetPoint(id_to_select) + if point_coordinates: + data_attributes["coordinates"] = list(point_coordinates) + + return { + "id": pipeline_id, + "picked_id": id_to_select, + "field_type": params.field_type.value, + "geode_id": geode_id, + "attributes": data_attributes, + } @exportRpc(viewer_prefix + viewer_schemas_dict["set_z_scaling"]["rpc"]) def setZScaling(self, rpc_params: RpcParams) -> None: diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index 786806e..4978dfe 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -60,7 +60,7 @@ class VtkPipeline: mapper: vtkMapper filter: vtkAlgorithm | None = None actor: vtkActor = field(default_factory=vtkActor) - hoverHighlight: HighlightPipeline = field(default_factory=HighlightPipeline) + highlight: HighlightPipeline = field(default_factory=HighlightPipeline) blockDataSets: list[vtkDataObject | None] = field(default_factory=list) blockGeodeIds: list[str] = field(default_factory=list) @@ -152,14 +152,14 @@ def reset_camera_clipping_range(self) -> None: else: renderer.ResetCameraClippingRange() - def updateHoverHighlight( + def update_highlight( self, pipeline: VtkPipeline, id_to_select: int, field_type: str, - dataset: vtkDataSet | None = None, + dataset: vtkDataObject | None = None, ) -> None: - node = pipeline.hoverHighlight.selectionNode + node = pipeline.highlight.selectionNode node.SetContentType(vtkSelectionNode.INDICES) node.SetFieldType( vtkSelectionNode.CELL if field_type == "CELL" else vtkSelectionNode.POINT @@ -169,15 +169,15 @@ def updateHoverHighlight( selection_list.InsertNextValue(id_to_select) node.SetSelectionList(selection_list) if dataset is not None: - pipeline.hoverHighlight.extractSelection.SetInputData(0, dataset) - pipeline.hoverHighlight.extractSelection.Modified() - pipeline.hoverHighlight.extractSelection.Update() - pipeline.hoverHighlight.actor.VisibilityOn() + pipeline.highlight.extractSelection.SetInputData(0, dataset) + pipeline.highlight.extractSelection.Modified() + pipeline.highlight.extractSelection.Update() + pipeline.highlight.actor.VisibilityOn() - def clearHoverHighlights(self, ids: list[str]) -> None: + def clear_highlights(self, ids: list[str]) -> None: for data_id in ids: pipeline = self.get_vtk_pipeline(data_id) - pipeline.hoverHighlight.actor.VisibilityOff() + pipeline.highlight.actor.VisibilityOff() def update_grid_scale_and_clipping_range(self) -> None: grid_scale = self.get_grid_scale()