Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions opengeodeweb_viewer_schemas.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,3 @@ wslink==1.12.4
yarl>=1
# via aiohttp

opengeodeweb-microservice==1.*,>=1.1.3
29 changes: 29 additions & 0 deletions src/opengeodeweb_viewer/object/object_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -15,6 +16,7 @@
from vtkmodules.vtkCommonDataModel import (
vtkDataObject,
vtkDataSet,
vtkSelectionNode,
)

# Local application imports
Expand Down Expand Up @@ -48,6 +50,7 @@ def registerObject(
resetCamara = False
renderer.AddActor(data.actor)
renderer.AddActor(data.highlightActor)
renderer.AddActor(data.hoverHighlightActor)
if resetCamara:
renderer.ResetCamera()

Expand All @@ -57,6 +60,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:
Expand Down Expand Up @@ -178,3 +182,28 @@ def highlight(
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()
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()
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())
1 change: 1 addition & 0 deletions src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def registerMesh(self, rpc_params: RpcParams) -> None:
self.highlight(
data.highlightActor, data.highlightMapper, 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)
Expand Down
1 change: 1 addition & 0 deletions src/opengeodeweb_viewer/rpc/model/model_protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +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.setupHoverHighlight(data)
iterator = geometry_output.NewTreeIterator()
iterator.InitTraversal()
while not iterator.IsDoneWithTraversal():
Expand Down
1 change: 1 addition & 0 deletions src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
24 changes: 24 additions & 0 deletions src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.json
Original file line number Diff line number Diff line change
@@ -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
}
20 changes: 20 additions & 0 deletions src/opengeodeweb_viewer/rpc/viewer/schemas/hover_highlight.py
Original file line number Diff line number Diff line change
@@ -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
34 changes: 32 additions & 2 deletions src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -303,6 +303,36 @@ 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()
self.clearHoverHighlights(params.ids)
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
self.render(-1)

@exportRpc(viewer_prefix + viewer_schemas_dict["set_z_scaling"]["rpc"])
def setZScaling(self, rpc_params: RpcParams) -> None:
validate_schema(
Expand Down
38 changes: 36 additions & 2 deletions src/opengeodeweb_viewer/vtk_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,16 @@
vtkRenderer,
vtkRenderWindow,
vtkCompositePolyDataMapper,
vtkDataSetMapper,
)
from vtkmodules.vtkCommonDataModel import vtkDataObject, vtkBoundingBox
from vtkmodules.vtkCommonCore import vtkStringArray
from vtkmodules.vtkCommonDataModel import (
vtkDataObject,
vtkBoundingBox,
vtkSelection,
vtkSelectionNode,
)
from vtkmodules.vtkFiltersExtraction import vtkExtractSelection
from vtkmodules.vtkCommonCore import vtkStringArray, vtkIdTypeArray
from vtkmodules.vtkRenderingAnnotation import vtkCubeAxesActor, vtkAxesActor
from vtkmodules.vtkInteractionWidgets import vtkOrientationMarkerWidget

Expand All @@ -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)
Expand Down Expand Up @@ -138,6 +150,28 @@ 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)
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)

pipeline.extractSelection.Modified()
pipeline.extractSelection.Update()
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:
Expand Down
Loading