Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
61200cd
temp schemas and logic
MaxNumerique May 13, 2026
7e0e5fe
refacto ?
MaxNumerique May 13, 2026
b144623
Apply prepare changes
MaxNumerique May 13, 2026
c3853af
refacto
MaxNumerique May 13, 2026
6af2cf5
Merge branch 'feat/highlightVertex' of https://github.com/Geode-solut…
MaxNumerique May 13, 2026
822ace2
Merge branch 'next' of https://github.com/Geode-solutions/OpenGeodeWe…
MaxNumerique May 15, 2026
a53e76e
Merge branch 'next' of https://github.com/Geode-solutions/OpenGeodeWe…
MaxNumerique May 15, 2026
09fde19
Merge branch 'feat/highlightVertex' of https://github.com/Geode-solut…
MaxNumerique May 15, 2026
17b16b7
models
MaxNumerique May 15, 2026
8d1e74e
Merge branch 'feat/highlightVertex' of https://github.com/Geode-solut…
MaxNumerique May 15, 2026
928e810
Apply prepare changes
MaxNumerique May 15, 2026
6c0611d
refacto
MaxNumerique May 15, 2026
75fe274
Merge branch 'feat/highlightVertex' of https://github.com/Geode-solut…
MaxNumerique May 15, 2026
15b6493
Apply prepare changes
MaxNumerique May 15, 2026
4154e71
color green
MaxNumerique May 15, 2026
855bd6b
Merge branch 'feat/highlightVertex' of https://github.com/Geode-solut…
MaxNumerique May 15, 2026
3ad5f45
SetRelativeCoincidentTopologyPolygonOffsetParameters for both highlights
MaxNumerique May 15, 2026
848e3a3
temp
MaxNumerique May 15, 2026
19227c5
harmonize logic between highlights methods
MaxNumerique May 15, 2026
8426339
Merge branch 'feat/highlightVertex' of https://github.com/Geode-solut…
MaxNumerique May 15, 2026
3805f42
Apply prepare changes
MaxNumerique May 15, 2026
cc69bee
highlight over setuphighlight
MaxNumerique May 15, 2026
8af8e37
Merge branch 'feat/highlightVertex' of https://github.com/Geode-solut…
MaxNumerique May 15, 2026
c443493
more refacto
MaxNumerique May 15, 2026
333ccf2
fix imports
MaxNumerique May 15, 2026
a135988
actor.SetUseBounds(False)
MaxNumerique May 18, 2026
2758704
highlight
MaxNumerique May 18, 2026
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 @@ -1927,6 +1927,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
32 changes: 22 additions & 10 deletions src/opengeodeweb_viewer/object/object_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
vtkDataSetMapper,
)
from vtkmodules.vtkCommonDataModel import (
vtkDataObject,
vtkDataSet,
)
from vtkmodules.vtkFiltersExtraction import vtkExtractSelection

# Local application imports
from opengeodeweb_viewer.vtk_protocol import VtkView, VtkPipeline
Expand Down Expand Up @@ -47,7 +47,7 @@ def registerObject(
if actor.visibility == True:
resetCamara = False
renderer.AddActor(data.actor)
renderer.AddActor(data.highlightActor)
renderer.AddActor(data.hoverHighlight.actor)
if resetCamara:
renderer.ResetCamera()

Expand All @@ -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.highlightActor)
renderer.RemoveActor(pipeline.hoverHighlight.actor)
self.deregister_object(data_id)

def SetVisibility(self, data_id: str, visibility: bool) -> None:
Expand Down Expand Up @@ -162,19 +162,31 @@ def clearColors(self, data_id: str) -> None:
output.GetCellData().SetActiveScalars("")
mapper.ScalarVisibilityOff()

def highlight(
self, actor: vtkActor, mapper: vtkMapper, input_dataset: vtkDataObject
) -> None:
mapper.SetInputDataObject(input_dataset)
def _apply_highlight_style(self, actor: vtkActor, mapper: vtkDataSetMapper) -> None:
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.SetLineWidth(4)
prop.SetPointSize(15)
prop.SetRenderPointsAsSpheres(True)
prop.SetLighting(True)
prop.SetLighting(False)
prop.SetEdgeVisibility(True)
prop.SetEdgeColor(0.12, 0.35, 0.30)
actor.SetMapper(mapper)
actor.VisibilityOff()
actor.SetUseBounds(False)

def highlight(self, pipeline: VtkPipeline) -> None:
highlight = pipeline.hoverHighlight
self._apply_highlight_style(highlight.actor, highlight.mapper)
input_port = (
pipeline.filter.GetOutputPort()
if pipeline.filter
else pipeline.reader.GetOutputPort()
)
highlight.selection.AddNode(highlight.selectionNode)
highlight.extractSelection.SetInputConnection(0, input_port)
highlight.extractSelection.SetInputData(1, highlight.selection)
highlight.mapper.SetInputConnection(highlight.extractSelection.GetOutputPort())
16 changes: 10 additions & 6 deletions src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.highlight(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 Expand Up @@ -177,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.hoverHighlight.mapper.SetInputDataObject(dataset)
else:
pipeline.hoverHighlight.mapper.SetInputConnection(
pipeline.hoverHighlight.extractSelection.GetOutputPort()
)
pipeline.hoverHighlight.actor.SetVisibility(params.visibility)
self.render(-1)
49 changes: 22 additions & 27 deletions src/opengeodeweb_viewer/rpc/model/model_protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
vtkCompositeDataSet,
vtkBoundingBox,
vtkDataSet,
vtkSelectionNode,
)
from vtkmodules.vtkRenderingCore import (
vtkCompositeDataDisplayAttributes,
vtkCompositePolyDataMapper,
vtkCompositeDataDisplayAttributes,
)
from vtkmodules.vtkFiltersCore import vtkAppendDataSets
from vtkmodules.vtkIOXML import vtkXMLMultiBlockDataReader
from vtkmodules.vtkFiltersGeometry import vtkGeometryFilter
from wslink import register as exportRpc # type: ignore
Expand Down Expand Up @@ -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.highlight(data)
iterator = geometry_output.NewTreeIterator()
iterator.InitTraversal()
while not iterator.IsDoneWithTraversal():
Expand All @@ -136,9 +134,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)
Expand Down Expand Up @@ -171,23 +166,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()
Comment on lines +170 to +179
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

En fait si on veut harmoniser et utiliser vtkSelectionNode.BLOCKS, on aura une sortie en vtkMultiBlocksDataSet, alors que le mapper qu'on a pourle highlight est vtkDataSetMapper et n'accepte que les objets qui héritent de vtkDataSet.

Donc soit on garde ce vtkAppendDataSets pour fusionner les blocs du vtkMultiBlocksDataSet extrait en un seul vkDataSet
ou
on change dynamiquement le type de mapper, mais je ne sais pas si ça complexifie trop pour juste ça ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pipeline.hoverHighlight.mapper.SetInputDataObject(append.GetOutput())
else:
pipeline.hoverHighlight.mapper.SetInputConnection(
pipeline.hoverHighlight.extractSelection.GetOutputPort()
)
pipeline.hoverHighlight.actor.SetVisibility(params.visibility)
self.render(-1)

@exportRpc(model_prefix + model_schemas_dict["get_blocks_bounds"]["rpc"])
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
43 changes: 41 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,45 @@ 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)
picker = vtkCellPicker(tolerance=0.005)
picker.Pick(params.x, params.y, 0, self.get_renderer())
self.clearHoverHighlights(params.ids)
actor = picker.GetActor()
pipeline = next(
Comment thread
MaxNumerique marked this conversation as resolved.
(
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()
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"])
def setZScaling(self, rpc_params: RpcParams) -> None:
validate_schema(
Expand Down
Loading
Loading