diff --git a/opengeodeweb_viewer_schemas.json b/opengeodeweb_viewer_schemas.json index be483a47..e406edce 100644 --- a/opengeodeweb_viewer_schemas.json +++ b/opengeodeweb_viewer_schemas.json @@ -2350,6 +2350,55 @@ ], "additionalProperties": false }, + "clipping_planes": { + "$id": "opengeodeweb_viewer.viewer.clipping_planes", + "rpc": "clipping_planes", + "type": "object", + "properties": { + "ids": { + "type": "array", + "items": { + "type": "string", + "minLength": 32, + "maxLength": 32 + } + }, + "planes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "origin": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3 + }, + "normal": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3 + } + }, + "required": [ + "origin", + "normal" + ], + "additionalProperties": false + } + } + }, + "required": [ + "ids", + "planes" + ], + "additionalProperties": false + }, "axes": { "$id": "opengeodeweb_viewer.viewer.axes", "rpc": "axes", diff --git a/requirements.txt b/requirements.txt index 344c705a..9108a15f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -63,4 +63,3 @@ wslink==1.12.4 yarl>=1 # via aiohttp -opengeodeweb-microservice==1.*,>=1.1.4 diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index 1f2de7cf..afde5cc5 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -1,25 +1,17 @@ -# Standard library imports -import os - # Third party imports -from vtkmodules.vtkIOXML import vtkXMLDataReader, vtkXMLImageDataReader -from vtkmodules.vtkCommonExecutionModel import vtkAlgorithm +from vtkmodules.vtkCommonDataModel import ( + vtkDataSet, + vtkMultiBlockDataSet, +) from vtkmodules.vtkRenderingCore import ( - vtkMapper, vtkActor, - vtkTexture, vtkCompositePolyDataMapper, - vtkCompositeDataDisplayAttributes, vtkDataSetMapper, ) -from vtkmodules.vtkCommonDataModel import ( - vtkDataSet, - vtkMultiBlockDataSet, -) -from vtkmodules.vtkFiltersExtraction import vtkExtractSelection # Local application imports -from opengeodeweb_viewer.vtk_protocol import VtkView, VtkPipeline +from opengeodeweb_viewer.vtk_pipeline import VtkPipeline +from opengeodeweb_viewer.vtk_protocol import VtkView class VtkObjectView(VtkView): @@ -133,28 +125,6 @@ def SetPointsColor( actor = self.get_vtk_pipeline(data_id).actor actor.GetProperty().SetVertexColor([red / 255, green / 255, blue / 255]) - def _prune_hidden_blocks( - self, - dataset: vtkMultiBlockDataSet, - visibility_attributes: vtkCompositeDataDisplayAttributes, - ) -> vtkMultiBlockDataSet: - # Recursively construct a new multi-block dataset excluding hidden blocks. - pruned = vtkMultiBlockDataSet() - pruned.SetNumberOfBlocks(dataset.GetNumberOfBlocks()) - for index in range(dataset.GetNumberOfBlocks()): - block = dataset.GetBlock(index) - if block is None: - continue - if not visibility_attributes.GetBlockVisibility(block): - continue - if isinstance(block, vtkMultiBlockDataSet): - pruned.SetBlock( - index, self._prune_hidden_blocks(block, visibility_attributes) - ) - else: - pruned.SetBlock(index, block) - return pruned - def SetBlocksVisibility( self, data_id: str, block_ids: list[int], visibility: bool ) -> None: @@ -164,16 +134,17 @@ def SetBlocksVisibility( raise Exception("Mapper is not a vtkCompositePolyDataMapper") blocks = pipeline.blockDataSets visibility_attributes = mapper.GetCompositeDataDisplayAttributes() + print(f"{visibility_attributes=}", flush=True) for block_id in block_ids: visibility_attributes.SetBlockVisibility(blocks[block_id], visibility) - dataset = (pipeline.filter or pipeline.reader).GetOutputDataObject(0) + dataset = mapper.GetInputDataObject(0, 0) if not isinstance(dataset, vtkMultiBlockDataSet): return # Re-build a pruned dataset for the dedicated pick mapper if pipeline.pick_mapper is None: pipeline.pick_mapper = vtkCompositePolyDataMapper() pipeline.pick_mapper.SetInputDataObject( - self._prune_hidden_blocks(dataset, visibility_attributes) + pipeline.prune_hidden_blocks(dataset, visibility_attributes) ) def SetBlocksColor( @@ -228,11 +199,9 @@ def _apply_highlight_style(self, actor: vtkActor, mapper: vtkDataSetMapper) -> N def highlight(self, pipeline: VtkPipeline) -> None: highlight = pipeline.highlight self._apply_highlight_style(highlight.actor, highlight.mapper) - input_port = ( - pipeline.filter.GetOutputPort() - if pipeline.filter - else pipeline.reader.GetOutputPort() - ) + if pipeline.filter.GetNumberOfInputConnections(0) == 0: + pipeline.filter.SetInputConnection(pipeline.reader.GetOutputPort()) + input_port = pipeline.filter.GetOutputPort() highlight.selection.AddNode(highlight.selectionNode) highlight.extractSelection.SetInputConnection(0, input_port) highlight.extractSelection.SetInputData(1, highlight.selection) diff --git a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py index 0834a2d7..b9b3720c 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py @@ -2,27 +2,23 @@ import os # Third party imports -from wslink import register as exportRpc # type: ignore +from opengeodeweb_microservice.database.data import Data +from opengeodeweb_microservice.schemas import get_schemas_dict from vtkmodules.vtkIOXML import vtkXMLGenericDataObjectReader, vtkXMLImageDataReader from vtkmodules.vtkRenderingCore import ( + vtkColorTransferFunction, vtkDataSetMapper, - vtkActor, vtkTexture, - vtkColorTransferFunction, ) -from vtkmodules.vtkCommonDataModel import vtkDataSet, vtkCellTypes -from vtkmodules.vtkCommonExecutionModel import vtkAlgorithm -from vtkmodules.vtkCommonDataModel import vtkPolyData -from opengeodeweb_microservice.database.data import Data -from opengeodeweb_microservice.schemas import get_schemas_dict +from wslink import register as exportRpc # type: ignore # Local application imports +from opengeodeweb_viewer.object.object_methods import VtkObjectView from opengeodeweb_viewer.utils_functions import ( - validate_schema, RpcParams, + validate_schema, ) -from opengeodeweb_viewer.object.object_methods import VtkObjectView -from opengeodeweb_viewer.vtk_protocol import VtkPipeline +from opengeodeweb_viewer.vtk_pipeline import VtkPipeline from . import schemas @@ -50,12 +46,9 @@ def registerMesh(self, rpc_params: RpcParams) -> None: reader = vtkXMLGenericDataObjectReader() reader.SetFileName(os.path.join(self.DATA_FOLDER_PATH, data_id, file_name)) reader.Update() - dataset = reader.GetOutputDataObject(0) - if dataset: - dataset.SetObjectName(params.name) mapper = vtkDataSetMapper() - mapper.SetInputConnection(reader.GetOutputPort()) data = VtkPipeline(reader, mapper) + self.setup_pipeline(data, params.name) self.highlight(data) self.registerObject(data_id, file_name, data) except Exception as e: @@ -107,16 +100,14 @@ def meshApplyTextures(self, rpc_params: RpcParams) -> None: texture = vtkTexture() texture.SetInputConnection(texture_reader.GetOutputPort()) texture.InterpolateOn() - reader = self.get_vtk_pipeline(mesh_id).reader - output = reader.GetOutputAsDataSet() - point_data = output.GetPointData() - for i in range(point_data.GetNumberOfArrays()): - array = point_data.GetArray(i) - if array.GetName() == tex_info.texture_name: - point_data.SetTCoords(array) - break - actor = self.get_vtk_pipeline(mesh_id).actor - actor.SetTexture(texture) + pipeline = self.get_vtk_pipeline(mesh_id) + output = pipeline.reader.GetOutputAsDataSet() + array = output.GetPointData().GetArray(tex_info.texture_name) + if array: + output.GetPointData().SetTCoords(array) + pipeline.filter.Modified() + pipeline.filter.Update() + pipeline.actor.SetTexture(texture) def displayAttributeOnVertices( self, @@ -127,10 +118,13 @@ def displayAttributeOnVertices( minimum: float, maximum: float, ) -> None: - reader = self.get_vtk_pipeline(data_id).reader - points = reader.GetOutputAsDataSet().GetPointData() - points.SetActiveScalars(name) - mapper = self.get_vtk_pipeline(data_id).mapper + pipeline = self.get_vtk_pipeline(data_id) + pipeline.reader.GetOutputAsDataSet().GetPointData().SetActiveScalars(name) + pipeline.filter.Update() + active_ds = pipeline.mapper.GetInputDataObject(0, 0) + if active_ds: + active_ds.GetPointData().SetActiveScalars(name) + mapper = pipeline.mapper mapper.ScalarVisibilityOn() mapper.SetScalarModeToUsePointData() mapper.SetArrayComponent(item) @@ -145,10 +139,13 @@ def displayAttributeOnCells( minimum: float, maximum: float, ) -> None: - reader = self.get_vtk_pipeline(data_id).reader - cells = reader.GetOutputAsDataSet().GetCellData() - cells.SetActiveScalars(name) - mapper = self.get_vtk_pipeline(data_id).mapper + pipeline = self.get_vtk_pipeline(data_id) + pipeline.reader.GetOutputAsDataSet().GetCellData().SetActiveScalars(name) + pipeline.filter.Update() + active_ds = pipeline.mapper.GetInputDataObject(0, 0) + if active_ds: + active_ds.GetCellData().SetActiveScalars(name) + mapper = pipeline.mapper mapper.ScalarVisibilityOn() mapper.SetScalarModeToUseCellData() mapper.SetArrayComponent(item) diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index 9753616b..cdc0a028 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -1,33 +1,31 @@ # Standard library imports import os +from typing import Optional, Protocol, TypedDict, cast # Third party imports +from opengeodeweb_microservice.schemas import get_schemas_dict from vtkmodules.vtkCommonDataModel import ( - vtkCompositeDataSet, vtkBoundingBox, + vtkCompositeDataSet, vtkDataSet, - vtkSelectionNode, ) +from vtkmodules.vtkCommonDataModel import vtkMultiBlockDataSet +from vtkmodules.vtkFiltersCore import vtkAppendDataSets +from vtkmodules.vtkIOXML import vtkXMLMultiBlockDataReader from vtkmodules.vtkRenderingCore import ( - vtkCompositePolyDataMapper, vtkCompositeDataDisplayAttributes, - vtkColorTransferFunction, + vtkCompositePolyDataMapper, ) -from vtkmodules.vtkFiltersCore import vtkAppendDataSets -from vtkmodules.vtkIOXML import vtkXMLMultiBlockDataReader -from vtkmodules.vtkFiltersGeometry import vtkGeometryFilter from wslink import register as exportRpc # type: ignore -from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports +from opengeodeweb_viewer.object.object_methods import VtkObjectView from opengeodeweb_viewer.utils_functions import ( - validate_schema, - RpcParams, deterministic_color, + RpcParams, + validate_schema, ) -from opengeodeweb_viewer.object.object_methods import VtkObjectView -from opengeodeweb_viewer.vtk_protocol import VtkPipeline, BlockStyle -from typing import Optional, List, TypedDict, Protocol +from opengeodeweb_viewer.vtk_pipeline import VtkPipeline from . import schemas @@ -60,78 +58,6 @@ class VtkModelView(VtkObjectView): def __init__(self) -> None: super().__init__() - def _get_block_style(self, pipeline: VtkPipeline, block_id: int) -> BlockStyle: - if block_id not in pipeline.block_styles: - style = BlockStyle( - name="", - attribute_location="point", - points=[], - minimum=0.0, - maximum=1.0, - item=0, - ) - pipeline.block_styles[block_id] = style - return pipeline.block_styles[block_id] - - def updateBlockColors(self, pipeline: VtkPipeline, block_id: int) -> None: - block = pipeline.blockDataSets[block_id] - if not isinstance(block, vtkDataSet): - return - - style = self._get_block_style(pipeline, block_id) - if not style["name"]: - block.GetPointData().SetActiveScalars("") - block.GetCellData().SetActiveScalars("") - return - - field_data = ( - block.GetPointData() - if style["attribute_location"] == "point" - else block.GetCellData() - ) - scalar_array = field_data.GetArray(style["name"]) - if not scalar_array: - return - - lut = vtkColorTransferFunction() - points = style["points"] - minimum = style["minimum"] - maximum = style["maximum"] - if points: - x_min, x_max = points[0], points[-4] - span = x_max - x_min - for i in range(0, len(points), 4): - x, r, g, b = points[i : i + 4] - new_x = ( - minimum + (x - x_min) / span * (maximum - minimum) - if span - else minimum - ) - lut.AddRGBPoint(new_x, r, g, b) - else: - lut.AddRGBPoint(minimum, 0, 0, 0) - lut.AddRGBPoint(maximum, 1, 1, 1) - - lut.SetRange(minimum, maximum) - rgba_colors = lut.MapScalars(scalar_array, 0, style.get("item", 0)) - rgba_colors.SetName(f"__colors_{style['name']}") - - field_data.AddArray(rgba_colors) - field_data.SetActiveScalars(rgba_colors.GetName()) - - other_field_data = ( - block.GetCellData() - if style["attribute_location"] == "point" - else block.GetPointData() - ) - other_field_data.SetActiveScalars("") - - mapper = pipeline.mapper - mapper.ScalarVisibilityOn() - mapper.SetColorModeToDirectScalars() - mapper.SetScalarModeToDefault() - mapper.Modified() - def apply_color( self, pipeline: VtkPipeline, @@ -143,13 +69,14 @@ def apply_color( if not isinstance(mapper, vtkCompositePolyDataMapper): return [] attr = mapper.GetCompositeDataDisplayAttributes() + print(f"{attr=}", flush=True) colors: list[ColorResult] = [] for block_id in block_ids: block_dataset = pipeline.blockDataSets[block_id] if isinstance(block_dataset, vtkDataSet): block_dataset.GetPointData().SetActiveScalars("") block_dataset.GetCellData().SetActiveScalars("") - self._get_block_style(pipeline, block_id)["name"] = "" + pipeline.get_block_style(block_id)["name"] = "" if color_mode == "random": geode_id = pipeline.blockGeodeIds[block_id] red, green, blue = deterministic_color(str(geode_id)) @@ -191,14 +118,14 @@ def displayAttributeOnVertices( ) -> None: pipeline = self.get_vtk_pipeline(data_id) for block_id in block_ids: - style = self._get_block_style(pipeline, block_id) + style = pipeline.get_block_style(block_id) style["name"] = name style["item"] = item style["attribute_location"] = "point" style["points"] = color_map style["minimum"] = minimum style["maximum"] = maximum - self.updateBlockColors(pipeline, block_id) + pipeline.update_block_colors(block_id) def displayAttributeOnCells( self, @@ -212,14 +139,14 @@ def displayAttributeOnCells( ) -> None: pipeline = self.get_vtk_pipeline(data_id) for block_id in block_ids: - style = self._get_block_style(pipeline, block_id) + style = pipeline.get_block_style(block_id) style["name"] = name style["item"] = item style["attribute_location"] = "cell" style["points"] = color_map style["minimum"] = minimum style["maximum"] = maximum - self.updateBlockColors(pipeline, block_id) + pipeline.update_block_colors(block_id) def setupColorMap( self, @@ -230,11 +157,11 @@ def setupColorMap( maximum: float, ) -> None: for block_id in block_ids: - style = self._get_block_style(pipeline, block_id) + style = pipeline.get_block_style(block_id) style["points"] = points style["minimum"] = minimum style["maximum"] = maximum - self.updateBlockColors(pipeline, block_id) + pipeline.update_block_colors(block_id) @exportRpc(model_prefix + model_schemas_dict["register"]["rpc"]) def registerModel(self, rpc_params: RpcParams) -> None: @@ -250,17 +177,13 @@ def registerModel(self, rpc_params: RpcParams) -> None: reader = vtkXMLMultiBlockDataReader() reader.SetFileName(os.path.join(self.DATA_FOLDER_PATH, data_id, file_name)) reader.Update() - filter = vtkGeometryFilter() - filter.SetInputConnection(reader.GetOutputPort()) - filter.Update() - geometry_output = filter.GetOutputDataObject(0) - if geometry_output: - geometry_output.SetObjectName(params.name) mapper = vtkCompositePolyDataMapper() - mapper.SetInputDataObject(geometry_output) attributes = vtkCompositeDataDisplayAttributes() mapper.SetCompositeDataDisplayAttributes(attributes) - data = VtkPipeline(reader, mapper, filter) + data = VtkPipeline(reader, mapper) + geometry_output = cast( + vtkMultiBlockDataSet, self.setup_pipeline(data, params.name) + ) self.highlight(data) iterator = geometry_output.NewTreeIterator() iterator.InitTraversal() diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py index 0fe2b748..ee2b4ce8 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py @@ -12,4 +12,5 @@ from .highlight import * from .grid_scale import * from .get_point_position import * +from .clipping_planes import * from .axes import * diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/clipping_planes.json b/src/opengeodeweb_viewer/rpc/viewer/schemas/clipping_planes.json new file mode 100644 index 00000000..83b38706 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/clipping_planes.json @@ -0,0 +1,48 @@ +{ + "rpc": "clipping_planes", + "type": "object", + "properties": { + "ids": { + "type": "array", + "items": { + "type": "string", + "minLength": 32, + "maxLength": 32 + } + }, + "planes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "origin": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3 + }, + "normal": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3 + } + }, + "required": [ + "origin", + "normal" + ], + "additionalProperties": false + } + } + }, + "required": [ + "ids", + "planes" + ], + "additionalProperties": false +} diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/clipping_planes.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/clipping_planes.py new file mode 100644 index 00000000..eb81c8e5 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/clipping_planes.py @@ -0,0 +1,21 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import List + + +@dataclass +class Plane(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + normal: List[float] + origin: List[float] + + +@dataclass +class ClippingPlanes(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + ids: List[str] + planes: List[Plane] diff --git a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py index 408fca26..7450b2bd 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -31,7 +31,7 @@ RpcParams, ) from opengeodeweb_viewer.vtk_protocol import VtkView -from . import schemas +from opengeodeweb_viewer.rpc.viewer import schemas class VtkViewerView(VtkView): @@ -362,6 +362,14 @@ def setHighlight( "attributes": data_attributes, } + @exportRpc(viewer_prefix + viewer_schemas_dict["clipping_planes"]["rpc"]) + def setClippingPlanes(self, rpc_params: RpcParams) -> None: + validate_schema( + rpc_params, self.viewer_schemas_dict["clipping_planes"], self.viewer_prefix + ) + params = schemas.ClippingPlanes.from_dict(rpc_params) + self.set_clipping_planes(params.ids, params.planes) + @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_pipeline.py b/src/opengeodeweb_viewer/vtk_pipeline.py new file mode 100644 index 00000000..2723aa99 --- /dev/null +++ b/src/opengeodeweb_viewer/vtk_pipeline.py @@ -0,0 +1,231 @@ +# Standard library imports +from dataclasses import dataclass, field +from typing import cast, Literal, TypedDict + +# Third party imports +from vtkmodules.vtkRenderingCore import ( + vtkActor, + vtkDataSetMapper, + vtkMapper, + vtkCompositePolyDataMapper, + vtkCompositeDataDisplayAttributes, + vtkColorTransferFunction, +) +from vtkmodules.vtkRenderingAnnotation import ( + vtkScalarBarActor, +) +from vtkmodules.vtkCommonDataModel import ( + vtkDataObject, + vtkDataSet, + vtkMultiBlockDataSet, + vtkSelection, + vtkSelectionNode, +) +from vtkmodules.vtkCommonExecutionModel import vtkAlgorithm +from vtkmodules.vtkFiltersExtraction import ( + vtkExtractGeometry, + vtkExtractSelection, +) +from vtkmodules.vtkFiltersGeometry import vtkGeometryFilter +from vtkmodules.vtkIOXML import vtkXMLReader + +# Local application imports +from opengeodeweb_microservice.database.data_types import ( + ViewerElementsType, + ViewerType, +) + + +@dataclass +class ViewerData: + id: str + viewable_file: str | None + viewer_object: ViewerType + 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) + + +class BlockStyle(TypedDict): + name: str + attribute_location: Literal["point", "cell"] + points: list[float] + minimum: float + maximum: float + item: int + + +@dataclass +class VtkPipeline: + reader: vtkXMLReader + mapper: vtkMapper + filter: vtkGeometryFilter = field(default_factory=vtkGeometryFilter) + actor: vtkActor = field(default_factory=vtkActor) + clipping_filter: vtkExtractGeometry | None = None + highlight: HighlightPipeline = field(default_factory=HighlightPipeline) + blockDataSets: list[vtkDataObject | None] = field(default_factory=list) + blockGeodeIds: list[str] = field(default_factory=list) + scalarBar: vtkScalarBarActor = field(default_factory=vtkScalarBarActor) + block_styles: dict[int, BlockStyle] = field(default_factory=dict) + pick_mapper: vtkMapper | None = None + + def extract_blocks( + self, multiblock: vtkDataObject | None + ) -> list[vtkDataObject | None]: + if not isinstance(multiblock, vtkMultiBlockDataSet): + return [] + blocks: list[vtkDataObject | None] = [] + iterator = multiblock.NewTreeIterator() + iterator.InitTraversal() + while not iterator.IsDoneWithTraversal(): + flat_index = iterator.GetCurrentFlatIndex() + blocks.extend([None] * (flat_index + 1 - len(blocks))) + blocks[flat_index] = iterator.GetCurrentDataObject() + iterator.GoToNextItem() + print( + f"[extract_blocks] Total slots={len(blocks)} (None count={blocks.count(None)}): " + f"{[(index, type(obj).__name__ if obj else None) for index, obj in enumerate(blocks)]}", + flush=True, + ) + return blocks + + def prune_hidden_blocks( + self, + dataset: vtkMultiBlockDataSet, + attributes: vtkCompositeDataDisplayAttributes, + ) -> vtkMultiBlockDataSet: + pruned = vtkMultiBlockDataSet() + pruned.SetNumberOfBlocks(dataset.GetNumberOfBlocks()) + for index in range(dataset.GetNumberOfBlocks()): + block = dataset.GetBlock(index) + if block and attributes.GetBlockVisibility(block): + child = ( + self.prune_hidden_blocks(block, attributes) + if isinstance(block, vtkMultiBlockDataSet) + else block + ) + pruned.SetBlock(index, child) + return pruned + + def get_block_style(self, block_id: int) -> BlockStyle: + if block_id not in self.block_styles: + style = BlockStyle( + name="", + attribute_location="point", + points=[], + minimum=0.0, + maximum=1.0, + item=0, + ) + self.block_styles[block_id] = style + return self.block_styles[block_id] + + def update_block_colors(self, block_id: int) -> None: + block = self.blockDataSets[block_id] + if not isinstance(block, vtkDataSet): + return + style = self.get_block_style(block_id) + if not style["name"]: + block.GetPointData().SetActiveScalars("") + block.GetCellData().SetActiveScalars("") + return + field_data = ( + block.GetPointData() + if style["attribute_location"] == "point" + else block.GetCellData() + ) + scalar_array = field_data.GetArray(style["name"]) + if not scalar_array: + return + + lut = vtkColorTransferFunction() + points = style["points"] + minimum = style["minimum"] + maximum = style["maximum"] + if points: + x_min, x_max = points[0], points[-4] + span = x_max - x_min + for i in range(0, len(points), 4): + x, r, g, b = points[i : i + 4] + new_x = ( + minimum + (x - x_min) / span * (maximum - minimum) + if span + else minimum + ) + lut.AddRGBPoint(new_x, r, g, b) + else: + lut.AddRGBPoint(minimum, 0, 0, 0) + lut.AddRGBPoint(maximum, 1, 1, 1) + + lut.SetRange(minimum, maximum) + rgba_colors = lut.MapScalars(scalar_array, 0, style.get("item", 0)) + rgba_colors.SetName(f"__colors_{style['name']}") + + field_data.AddArray(rgba_colors) + field_data.SetActiveScalars(rgba_colors.GetName()) + + other_field_data = ( + block.GetCellData() + if style["attribute_location"] == "point" + else block.GetPointData() + ) + other_field_data.SetActiveScalars("") + + if isinstance(self.mapper, vtkCompositePolyDataMapper): + attributes = self.mapper.GetCompositeDataDisplayAttributes() + if attributes: + attributes.RemoveBlockColor(block) + self.mapper.ScalarVisibilityOn() + self.mapper.SetColorModeToDirectScalars() + self.mapper.SetScalarModeToDefault() + self.mapper.Modified() + + def sync_block_display_attributes( + self, new_blocks: list[vtkDataObject | None] + ) -> None: + mapper = cast(vtkCompositePolyDataMapper, self.mapper) + attributes = mapper.GetCompositeDataDisplayAttributes() + color_rgb = [0.0, 0.0, 0.0] + for source_block, destination_block in zip(self.blockDataSets, new_blocks): + if source_block and destination_block: + if attributes.HasBlockColor(source_block): + attributes.GetBlockColor(source_block, color_rgb) + attributes.SetBlockColor(destination_block, color_rgb) + else: + attributes.RemoveBlockColor(destination_block) + if attributes.HasBlockVisibility(source_block): + attributes.SetBlockVisibility( + destination_block, attributes.GetBlockVisibility(source_block) + ) + if attributes.HasBlockOpacity(source_block): + attributes.SetBlockOpacity( + destination_block, attributes.GetBlockOpacity(source_block) + ) + self.blockDataSets = new_blocks + for block_id in self.block_styles: + self.update_block_colors(block_id) + + def restore_active_scalars(self, target: vtkDataSet) -> None: + source = self.reader.GetOutputAsDataSet() + if active_points := source.GetPointData().GetScalars(): + target.GetPointData().SetActiveScalars(active_points.GetName()) + if active_cells := source.GetCellData().GetScalars(): + target.GetCellData().SetActiveScalars(active_cells.GetName()) + + def sync_composite_pipeline(self, dataset: vtkDataObject) -> None: + new_blocks = self.extract_blocks(dataset) + self.sync_block_display_attributes(new_blocks) + self.mapper.SetInputDataObject(dataset) + if self.pick_mapper and isinstance(dataset, vtkMultiBlockDataSet): + mapper = cast(vtkCompositePolyDataMapper, self.mapper) + attributes = mapper.GetCompositeDataDisplayAttributes() + self.pick_mapper.SetInputDataObject( + self.prune_hidden_blocks(dataset, attributes) + ) diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index ef8a6f36..d6c959ba 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -1,87 +1,44 @@ # Standard library imports import math import os -from typing import cast, Any, Literal, TypedDict -from dataclasses import dataclass, field +from typing import Any, cast # Third party imports import vtkmodules.vtkRenderingOpenGL2 from vtkmodules.web import protocols as vtk_protocols -from vtkmodules.vtkIOXML import ( - vtkXMLReader, -) from vtkmodules.vtkWebCore import vtkWebApplication -from vtkmodules.vtkCommonExecutionModel import vtkAlgorithm from vtkmodules.vtkRenderingCore import ( vtkActor, - vtkMapper, + vtkCellPicker, + vtkCompositePolyDataMapper, vtkRenderer, vtkRenderWindow, - vtkDataSetMapper, - vtkCompositePolyDataMapper, - vtkCellPicker, - vtkHardwarePicker, ) from vtkmodules.vtkCommonDataModel import ( + vtkBoundingBox, vtkDataObject, vtkDataSet, - vtkBoundingBox, - vtkSelection, + vtkImplicitBoolean, + vtkPlane, vtkSelectionNode, ) -from vtkmodules.vtkFiltersExtraction import vtkExtractSelection -from vtkmodules.vtkCommonCore import vtkStringArray, vtkIdTypeArray +from vtkmodules.vtkFiltersExtraction import vtkExtractGeometry +from vtkmodules.vtkFiltersGeometry import vtkGeometryFilter +from vtkmodules.vtkCommonCore import vtkIdTypeArray, vtkStringArray from vtkmodules.vtkRenderingAnnotation import ( - vtkCubeAxesActor, vtkAxesActor, - vtkScalarBarActor, + vtkCubeAxesActor, ) from vtkmodules.vtkInteractionWidgets import vtkOrientationMarkerWidget # Local application imports -from opengeodeweb_microservice.database.connection import get_session, init_database +from opengeodeweb_microservice.database.connection import get_session from opengeodeweb_microservice.database.data import Data -from opengeodeweb_microservice.database.data_types import ViewerType, ViewerElementsType - - -@dataclass -class ViewerData: - id: str - viewable_file: str | None - viewer_object: ViewerType - 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) - - -class BlockStyle(TypedDict): - name: str - attribute_location: Literal["point", "cell"] - points: list[float] - minimum: float - maximum: float - item: int - - -@dataclass -class VtkPipeline: - reader: vtkXMLReader - mapper: vtkMapper - filter: vtkAlgorithm | None = None - actor: vtkActor = field(default_factory=vtkActor) - highlight: HighlightPipeline = field(default_factory=HighlightPipeline) - blockDataSets: list[vtkDataObject | None] = field(default_factory=list) - blockGeodeIds: list[str] = field(default_factory=list) - scalarBar: vtkScalarBarActor = field(default_factory=vtkScalarBarActor) - block_styles: dict[int, BlockStyle] = field(default_factory=dict) - pick_mapper: vtkMapper | None = None +from opengeodeweb_viewer.rpc.viewer.schemas.clipping_planes import Plane +from opengeodeweb_viewer.vtk_pipeline import ( + ViewerData, + VtkPipeline, +) class VtkTypingMixin: @@ -167,10 +124,21 @@ def reset_camera_clipping_range(self) -> None: if grid_scale is not None and grid_scale.GetVisibility(): grid_scale.SetUseBounds(True) renderer.ResetCameraClippingRange() - grid_scale.SetUseBounds(False) else: renderer.ResetCameraClippingRange() + def setup_pipeline(self, pipeline: VtkPipeline, name: str) -> vtkDataObject | None: + pipeline.filter.SetInputConnection(pipeline.reader.GetOutputPort()) + pipeline.filter.Update() + geometry_output: vtkDataObject | None = pipeline.filter.GetOutputDataObject(0) + if geometry_output: + geometry_output.SetObjectName(name) + if isinstance(pipeline.mapper, vtkCompositePolyDataMapper): + pipeline.mapper.SetInputDataObject(geometry_output) + else: + pipeline.mapper.SetInputConnection(pipeline.filter.GetOutputPort()) + return geometry_output + def update_highlight( self, pipeline: VtkPipeline, @@ -187,8 +155,8 @@ def update_highlight( selection_list.SetNumberOfComponents(1) selection_list.InsertNextValue(id_to_select) node.SetSelectionList(selection_list) - if dataset is not None: - pipeline.highlight.extractSelection.SetInputData(0, dataset) + target_dataset = dataset or pipeline.mapper.GetInputDataObject(0, 0) + pipeline.highlight.extractSelection.SetInputData(0, target_dataset) pipeline.highlight.extractSelection.Modified() pipeline.highlight.extractSelection.Update() pipeline.highlight.actor.VisibilityOn() @@ -198,6 +166,41 @@ def clear_highlights(self, data_ids: list[str]) -> None: pipeline = self.get_vtk_pipeline(data_id) pipeline.highlight.actor.VisibilityOff() + def set_clipping_planes( + self, data_ids: list[str], planes_data: list[Plane] + ) -> None: + for data_id in data_ids: + pipeline = self.get_vtk_pipeline(data_id) + is_composite = isinstance(pipeline.mapper, vtkCompositePolyDataMapper) + if planes_data: + clipping_filter = vtkExtractGeometry() + clipping_filter.SetInputConnection(pipeline.reader.GetOutputPort()) + implicit_boolean = vtkImplicitBoolean() + implicit_boolean.SetOperationTypeToIntersection() + for plane_info in planes_data: + plane = vtkPlane() + plane.SetOrigin(plane_info.origin) + plane.SetNormal(plane_info.normal) + implicit_boolean.AddFunction(plane) + clipping_filter.SetImplicitFunction(implicit_boolean) + pipeline.clipping_filter = clipping_filter + input_port = clipping_filter.GetOutputPort() + else: + pipeline.clipping_filter = None + input_port = pipeline.reader.GetOutputPort() + pipeline.filter.SetInputConnection(input_port) + pipeline.filter.Update() + filtered_dataset = pipeline.filter.GetOutputDataObject(0) + if is_composite: + pipeline.sync_composite_pipeline(filtered_dataset) + else: + pipeline.mapper.SetInputConnection(input_port) + pipeline.restore_active_scalars( + cast(vtkDataSet, filtered_dataset) + if planes_data + else pipeline.reader.GetOutputAsDataSet() + ) + def swap_pick_mappers(self, data_ids: list[str], use_pick_mapper: bool) -> None: # Swap actor mappers between the default and the pick_mapper (where hidden blocks are pruned). for data_id in data_ids: @@ -386,16 +389,13 @@ def get_dist(axis: int) -> float: self.reset_camera_clipping_range() def update_scalar_bars_layout(self) -> None: - visible_bars = [] - for data_id, pipeline in self.get_data_base().items(): - if ( - pipeline.scalarBar.GetVisibility() - and pipeline.scalarBar.GetLookupTable() is not None - ): - visible_bars.append((data_id, pipeline.scalarBar)) - - n = len(visible_bars) - if n == 0: + visible_bars = [ + (data_id, pipeline) + for data_id, pipeline in self.get_data_base().items() + if pipeline.scalarBar.GetVisibility() + and pipeline.scalarBar.GetLookupTable() is not None + ] + if not visible_bars: return start_x = 0.22 @@ -407,25 +407,16 @@ def update_scalar_bars_layout(self) -> None: actual_width = 0.10 row_height = 0.12 - for i, (data_id, bar) in enumerate(visible_bars): - pipeline = self.get_vtk_pipeline(data_id) - if pipeline.filter: - dataset = pipeline.filter.GetOutputDataObject(0) - else: - dataset = pipeline.reader.GetOutputDataObject(0) - - attr_name = "" - if dataset: - pd = dataset.GetPointData().GetScalars() - cd = dataset.GetCellData().GetScalars() - if pd: - attr_name = pd.GetName() - elif cd: - attr_name = cd.GetName() - - if not attr_name: - attr_name = "Attribute" - + for i, (data_id, pipeline) in enumerate(visible_bars): + bar = pipeline.scalarBar + dataset = pipeline.filter.GetOutputDataObject(0) + scalars = ( + dataset.GetPointData().GetScalars() + or dataset.GetCellData().GetScalars() + if dataset + else None + ) + attr_name = scalars.GetName() if scalars else "Attribute" data_name = ( dataset.GetObjectName() if dataset and dataset.GetObjectName() diff --git a/tests/data/images/mesh/cells/clipping_plane.jpeg b/tests/data/images/mesh/cells/clipping_plane.jpeg new file mode 100644 index 00000000..917361bf Binary files /dev/null and b/tests/data/images/mesh/cells/clipping_plane.jpeg differ diff --git a/tests/data/images/mesh/edges/clipping_plane.jpeg b/tests/data/images/mesh/edges/clipping_plane.jpeg new file mode 100644 index 00000000..164d73d1 Binary files /dev/null and b/tests/data/images/mesh/edges/clipping_plane.jpeg differ diff --git a/tests/data/images/mesh/polygons/clipping_plane.jpeg b/tests/data/images/mesh/polygons/clipping_plane.jpeg new file mode 100644 index 00000000..164d73d1 Binary files /dev/null and b/tests/data/images/mesh/polygons/clipping_plane.jpeg differ diff --git a/tests/data/images/mesh/polyhedra/clipping_plane.jpeg b/tests/data/images/mesh/polyhedra/clipping_plane.jpeg new file mode 100644 index 00000000..08a83979 Binary files /dev/null and b/tests/data/images/mesh/polyhedra/clipping_plane.jpeg differ diff --git a/tests/data/images/model/blocks/clipping_plane.jpeg b/tests/data/images/model/blocks/clipping_plane.jpeg new file mode 100644 index 00000000..b79e82f6 Binary files /dev/null and b/tests/data/images/model/blocks/clipping_plane.jpeg differ diff --git a/tests/data/images/model/lines/clipping_plane.jpeg b/tests/data/images/model/lines/clipping_plane.jpeg new file mode 100644 index 00000000..7ef71b2d Binary files /dev/null and b/tests/data/images/model/lines/clipping_plane.jpeg differ diff --git a/tests/data/images/model/surfaces/clipping_plane.jpeg b/tests/data/images/model/surfaces/clipping_plane.jpeg new file mode 100644 index 00000000..713d813f Binary files /dev/null and b/tests/data/images/model/surfaces/clipping_plane.jpeg differ diff --git a/tests/mesh/cells/attribute/cell/test_cells_attribute_cell_protocols.py b/tests/mesh/cells/attribute/cell/test_cells_attribute_cell_protocols.py index 711a7fd4..ecc1133e 100644 --- a/tests/mesh/cells/attribute/cell/test_cells_attribute_cell_protocols.py +++ b/tests/mesh/cells/attribute/cell/test_cells_attribute_cell_protocols.py @@ -11,7 +11,7 @@ from tests.conftest import ServerMonitor # Local constants -mesh_id = "123456789" +mesh_id = "12345678901234567890123456789012" def test_register(server: ServerMonitor, dataset_factory: Callable[..., str]) -> None: diff --git a/tests/mesh/cells/attribute/vertex/test_cells_attribute_vertex_protocols.py b/tests/mesh/cells/attribute/vertex/test_cells_attribute_vertex_protocols.py index 58bd66d2..7a9baa69 100644 --- a/tests/mesh/cells/attribute/vertex/test_cells_attribute_vertex_protocols.py +++ b/tests/mesh/cells/attribute/vertex/test_cells_attribute_vertex_protocols.py @@ -11,7 +11,7 @@ from tests.conftest import ServerMonitor # Local constants -mesh_id = "123456789" +mesh_id = "12345678901234567890123456789012" def test_register(server: ServerMonitor, dataset_factory: Callable[..., str]) -> None: diff --git a/tests/mesh/cells/test_mesh_cells_protocols.py b/tests/mesh/cells/test_mesh_cells_protocols.py index 9da03dbe..47aa5e45 100644 --- a/tests/mesh/cells/test_mesh_cells_protocols.py +++ b/tests/mesh/cells/test_mesh_cells_protocols.py @@ -4,13 +4,14 @@ # Third party imports from opengeodeweb_viewer.rpc.mesh.mesh_protocols import VtkMeshView from opengeodeweb_viewer.rpc.mesh.cells.cells_protocols import VtkMeshCellsView +from opengeodeweb_viewer.rpc.viewer.viewer_protocols import VtkViewerView # Local application imports from tests.mesh.test_mesh_protocols import test_register_mesh from tests.conftest import ServerMonitor # Local constants -mesh_id = "123456789" +mesh_id = "12345678901234567890123456789012" def test_register(server: ServerMonitor, dataset_factory: Callable[..., str]) -> None: @@ -52,3 +53,27 @@ def test_cells_visibility( [{"id": mesh_id, "visibility": False}], ) assert server.compare_image("mesh/cells/visibility.jpeg") == True + + +def test_cells_clipping_plane( + server: ServerMonitor, dataset_factory: Callable[..., str] +) -> None: + + test_register(server, dataset_factory) + + server.call( + VtkViewerView.viewer_prefix + + VtkViewerView.viewer_schemas_dict["clipping_planes"]["rpc"], + [ + { + "ids": [mesh_id], + "planes": [ + { + "origin": [262.0, 387.0, 0.0], + "normal": [1.0, 1.0, 0.0], + } + ], + } + ], + ) + assert server.compare_image("mesh/cells/clipping_plane.jpeg") == True diff --git a/tests/mesh/edges/attribute/edge/test_edges_attribute_edge_protocols.py b/tests/mesh/edges/attribute/edge/test_edges_attribute_edge_protocols.py index dab93f18..92a20c72 100644 --- a/tests/mesh/edges/attribute/edge/test_edges_attribute_edge_protocols.py +++ b/tests/mesh/edges/attribute/edge/test_edges_attribute_edge_protocols.py @@ -11,7 +11,7 @@ from tests.conftest import ServerMonitor # Local constants -mesh_id = "123456789" +mesh_id = "12345678901234567890123456789012" def test_register(server: ServerMonitor, dataset_factory: Callable[..., str]) -> None: diff --git a/tests/mesh/edges/attribute/vertex/test_edges_attribute_vertex_protocols.py b/tests/mesh/edges/attribute/vertex/test_edges_attribute_vertex_protocols.py index ac75fdb6..5de92b82 100644 --- a/tests/mesh/edges/attribute/vertex/test_edges_attribute_vertex_protocols.py +++ b/tests/mesh/edges/attribute/vertex/test_edges_attribute_vertex_protocols.py @@ -11,7 +11,7 @@ from tests.conftest import ServerMonitor # Local constants -mesh_id = "123456789" +mesh_id = "12345678901234567890123456789012" def test_register(server: ServerMonitor, dataset_factory: Callable[..., str]) -> None: diff --git a/tests/mesh/edges/test_mesh_edges_protocols.py b/tests/mesh/edges/test_mesh_edges_protocols.py index b6b3ed77..d123b957 100644 --- a/tests/mesh/edges/test_mesh_edges_protocols.py +++ b/tests/mesh/edges/test_mesh_edges_protocols.py @@ -4,11 +4,15 @@ # Third party imports from opengeodeweb_viewer.rpc.mesh.mesh_protocols import VtkMeshView from opengeodeweb_viewer.rpc.mesh.edges.edges_protocols import VtkMeshEdgesView +from opengeodeweb_viewer.rpc.viewer.viewer_protocols import VtkViewerView # Local application imports from tests.mesh.test_mesh_protocols import test_register_mesh from tests.conftest import ServerMonitor +# Local constants +mesh_id = "12345678901234567890123456789012" + def test_edges_visibility( server: ServerMonitor, dataset_factory: Callable[..., str] @@ -18,7 +22,7 @@ def test_edges_visibility( server.call( VtkMeshEdgesView.mesh_edges_prefix + VtkMeshEdgesView.mesh_edges_schemas_dict["visibility"]["rpc"], - [{"id": "123456789", "visibility": True}], + [{"id": mesh_id, "visibility": True}], ) assert server.compare_image("mesh/edges/visibility.jpeg") == True @@ -33,7 +37,7 @@ def test_edges_color( + VtkMeshEdgesView.mesh_edges_schemas_dict["color"]["rpc"], [ { - "id": "123456789", + "id": mesh_id, "color": {"red": 255, "green": 0, "blue": 0, "alpha": 0.5}, } ], @@ -45,25 +49,48 @@ def test_edges_with_edged_curve( server: ServerMonitor, dataset_factory: Callable[..., str] ) -> None: dataset_factory( - id="123456789", viewable_file="edged_curve.vtp", viewer_elements_type="edges" + id=mesh_id, viewable_file="edged_curve.vtp", viewer_elements_type="edges" ) server.call( VtkMeshView.mesh_prefix + VtkMeshView.mesh_schemas_dict["register"]["rpc"], - [{"id": "123456789", "name": "edged_curve.vtp"}], + [{"id": mesh_id, "name": "edged_curve.vtp"}], ) assert server.compare_image("mesh/edges/register_edged_curve.jpeg") == True server.call( VtkMeshEdgesView.mesh_edges_prefix + VtkMeshEdgesView.mesh_edges_schemas_dict["color"]["rpc"], - [{"id": "123456789", "color": {"red": 255, "green": 0, "blue": 0, "alpha": 1}}], + [{"id": mesh_id, "color": {"red": 255, "green": 0, "blue": 0, "alpha": 1}}], ) assert server.compare_image("mesh/edges/edged_curve_color.jpeg") == True server.call( VtkMeshEdgesView.mesh_edges_prefix + VtkMeshEdgesView.mesh_edges_schemas_dict["visibility"]["rpc"], - [{"id": "123456789", "visibility": False}], + [{"id": mesh_id, "visibility": False}], ) assert server.compare_image("mesh/edges/edged_curve_visibility.jpeg") == True + + +def test_edges_clipping_plane( + server: ServerMonitor, dataset_factory: Callable[..., str] +) -> None: + test_register_mesh(server, dataset_factory) + + server.call( + VtkViewerView.viewer_prefix + + VtkViewerView.viewer_schemas_dict["clipping_planes"]["rpc"], + [ + { + "ids": [mesh_id], + "planes": [ + { + "origin": [0.0, 2.5, 0.0], + "normal": [1.0, 0.0, 1.0], + } + ], + } + ], + ) + assert server.compare_image("mesh/edges/clipping_plane.jpeg") == True diff --git a/tests/mesh/points/attribute/vertex/test_points_attribute_vertex_protocols.py b/tests/mesh/points/attribute/vertex/test_points_attribute_vertex_protocols.py index 20da3916..91f74233 100644 --- a/tests/mesh/points/attribute/vertex/test_points_attribute_vertex_protocols.py +++ b/tests/mesh/points/attribute/vertex/test_points_attribute_vertex_protocols.py @@ -11,7 +11,7 @@ from tests.conftest import ServerMonitor # Local constants -mesh_id = "123456789" +mesh_id = "12345678901234567890123456789012" def test_register(server: ServerMonitor, dataset_factory: Callable[..., str]) -> None: diff --git a/tests/mesh/points/test_mesh_points_protocols.py b/tests/mesh/points/test_mesh_points_protocols.py index 256ad2e4..8100052a 100644 --- a/tests/mesh/points/test_mesh_points_protocols.py +++ b/tests/mesh/points/test_mesh_points_protocols.py @@ -15,7 +15,7 @@ def test_points_visibility( server: ServerMonitor, dataset_factory: Callable[..., str] ) -> None: - mesh_id = "123456789" + mesh_id = "12345678901234567890123456789012" test_register_mesh(server, dataset_factory) server.call( @@ -29,7 +29,7 @@ def test_points_visibility( def test_points_size( server: ServerMonitor, dataset_factory: Callable[..., str] ) -> None: - mesh_id = "123456789" + mesh_id = "12345678901234567890123456789012" test_points_visibility(server, dataset_factory) server.call( @@ -43,7 +43,7 @@ def test_points_size( def test_points_color( server: ServerMonitor, dataset_factory: Callable[..., str] ) -> None: - mesh_id = "123456789" + mesh_id = "12345678901234567890123456789012" test_points_size(server, dataset_factory) server.call( diff --git a/tests/mesh/polygons/attribute/polygon/test_polygons_attribute_polygon_protocols.py b/tests/mesh/polygons/attribute/polygon/test_polygons_attribute_polygon_protocols.py index 84739dee..aa161317 100644 --- a/tests/mesh/polygons/attribute/polygon/test_polygons_attribute_polygon_protocols.py +++ b/tests/mesh/polygons/attribute/polygon/test_polygons_attribute_polygon_protocols.py @@ -11,7 +11,7 @@ from tests.conftest import ServerMonitor # Local constants -mesh_id = "123456789" +mesh_id = "12345678901234567890123456789012" def test_register(server: ServerMonitor, dataset_factory: Callable[..., str]) -> None: diff --git a/tests/mesh/polygons/attribute/vertex/test_polygons_attribute_vertex_protocols.py b/tests/mesh/polygons/attribute/vertex/test_polygons_attribute_vertex_protocols.py index 00f0b2c8..2ec8c4bf 100644 --- a/tests/mesh/polygons/attribute/vertex/test_polygons_attribute_vertex_protocols.py +++ b/tests/mesh/polygons/attribute/vertex/test_polygons_attribute_vertex_protocols.py @@ -11,7 +11,7 @@ from tests.conftest import ServerMonitor # Local constants -mesh_id = "123456789" +mesh_id = "12345678901234567890123456789012" def test_register(server: ServerMonitor, dataset_factory: Callable[..., str]) -> None: diff --git a/tests/mesh/polygons/test_mesh_polygons_protocols.py b/tests/mesh/polygons/test_mesh_polygons_protocols.py index f74acb28..e9fa585d 100644 --- a/tests/mesh/polygons/test_mesh_polygons_protocols.py +++ b/tests/mesh/polygons/test_mesh_polygons_protocols.py @@ -4,11 +4,15 @@ # Third party imports from opengeodeweb_viewer.rpc.mesh.mesh_protocols import VtkMeshView from opengeodeweb_viewer.rpc.mesh.polygons.polygons_protocols import VtkMeshPolygonsView +from opengeodeweb_viewer.rpc.viewer.viewer_protocols import VtkViewerView # Local application imports from tests.mesh.test_mesh_protocols import test_register_mesh from tests.conftest import ServerMonitor +# Local constants +mesh_id = "12345678901234567890123456789012" + def test_polygons_color( server: ServerMonitor, dataset_factory: Callable[..., str] @@ -21,7 +25,7 @@ def test_polygons_color( + VtkMeshPolygonsView.mesh_polygons_schemas_dict["color"]["rpc"], [ { - "id": "123456789", + "id": mesh_id, "color": {"red": 255, "green": 0, "blue": 0, "alpha": 1.0}, } ], @@ -38,6 +42,30 @@ def test_polygons_visibility( server.call( VtkMeshPolygonsView.mesh_polygons_prefix + VtkMeshPolygonsView.mesh_polygons_schemas_dict["visibility"]["rpc"], - [{"id": "123456789", "visibility": False}], + [{"id": mesh_id, "visibility": False}], ) assert server.compare_image("mesh/polygons/visibility.jpeg") == True + + +def test_polygons_clipping_plane( + server: ServerMonitor, dataset_factory: Callable[..., str] +) -> None: + + test_register_mesh(server, dataset_factory) + + server.call( + VtkViewerView.viewer_prefix + + VtkViewerView.viewer_schemas_dict["clipping_planes"]["rpc"], + [ + { + "ids": [mesh_id], + "planes": [ + { + "origin": [0.0, 2.5, 0.0], + "normal": [1.0, 0.0, 1.0], + } + ], + } + ], + ) + assert server.compare_image("mesh/polygons/clipping_plane.jpeg") == True diff --git a/tests/mesh/polyhedra/attribute/polyhedron/test_polyhedra_attribute_polyhedron_protocols.py b/tests/mesh/polyhedra/attribute/polyhedron/test_polyhedra_attribute_polyhedron_protocols.py index 0a6d9b5a..f60da143 100644 --- a/tests/mesh/polyhedra/attribute/polyhedron/test_polyhedra_attribute_polyhedron_protocols.py +++ b/tests/mesh/polyhedra/attribute/polyhedron/test_polyhedra_attribute_polyhedron_protocols.py @@ -11,7 +11,7 @@ from tests.conftest import ServerMonitor # Local constants -mesh_id = "123456789" +mesh_id = "12345678901234567890123456789012" def test_register(server: ServerMonitor, dataset_factory: Callable[..., str]) -> None: diff --git a/tests/mesh/polyhedra/attribute/vertex/test_polyhedra_attribute_vertex_protocols.py b/tests/mesh/polyhedra/attribute/vertex/test_polyhedra_attribute_vertex_protocols.py index a467cf29..1412c18f 100644 --- a/tests/mesh/polyhedra/attribute/vertex/test_polyhedra_attribute_vertex_protocols.py +++ b/tests/mesh/polyhedra/attribute/vertex/test_polyhedra_attribute_vertex_protocols.py @@ -11,7 +11,7 @@ from tests.conftest import ServerMonitor # Local constants -mesh_id = "123456789" +mesh_id = "12345678901234567890123456789012" def test_register(server: ServerMonitor, dataset_factory: Callable[..., str]) -> None: diff --git a/tests/mesh/polyhedra/test_mesh_polyhedra_protocols.py b/tests/mesh/polyhedra/test_mesh_polyhedra_protocols.py index ebc3b2b8..2aa0e11d 100644 --- a/tests/mesh/polyhedra/test_mesh_polyhedra_protocols.py +++ b/tests/mesh/polyhedra/test_mesh_polyhedra_protocols.py @@ -6,23 +6,27 @@ from opengeodeweb_viewer.rpc.mesh.polyhedra.polyhedra_protocols import ( VtkMeshPolyhedraView, ) +from opengeodeweb_viewer.rpc.viewer.viewer_protocols import VtkViewerView # Local application imports from tests.conftest import ServerMonitor +# Local constants +mesh_id = "12345678901234567890123456789012" + def test_register_mesh( server: ServerMonitor, dataset_factory: Callable[..., str] ) -> None: dataset_factory( - id="123456789", + id=mesh_id, viewable_file="polyhedron_attribute.vtu", viewer_elements_type="polyhedra", ) server.call( VtkMeshView.mesh_prefix + VtkMeshView.mesh_schemas_dict["register"]["rpc"], - [{"id": "123456789", "name": "polyhedron_attribute.vtu"}], + [{"id": mesh_id, "name": "polyhedron_attribute.vtu"}], ) assert server.compare_image("mesh/polyhedra/register.jpeg") == True @@ -37,7 +41,7 @@ def test_polyhedra_color( + VtkMeshPolyhedraView.mesh_polyhedra_schemas_dict["color"]["rpc"], [ { - "id": "123456789", + "id": mesh_id, "color": {"red": 255, "green": 0, "blue": 0, "alpha": 1.0}, } ], @@ -53,6 +57,30 @@ def test_polyhedra_visibility( server.call( VtkMeshPolyhedraView.mesh_polyhedra_prefix + VtkMeshPolyhedraView.mesh_polyhedra_schemas_dict["visibility"]["rpc"], - [{"id": "123456789", "visibility": False}], + [{"id": mesh_id, "visibility": False}], ) assert server.compare_image("mesh/polyhedra/visibility.jpeg") == True + + +def test_polyhedra_clipping_plane( + server: ServerMonitor, dataset_factory: Callable[..., str] +) -> None: + + test_register_mesh(server, dataset_factory) + + server.call( + VtkViewerView.viewer_prefix + + VtkViewerView.viewer_schemas_dict["clipping_planes"]["rpc"], + [ + { + "ids": [mesh_id], + "planes": [ + { + "origin": [0.5, 0.5, 0.5], + "normal": [-1.0, 0.0, 0.0], + } + ], + } + ], + ) + assert server.compare_image("mesh/polyhedra/clipping_plane.jpeg") == True diff --git a/tests/mesh/test_mesh_protocols.py b/tests/mesh/test_mesh_protocols.py index e696cdb4..a751ffdc 100644 --- a/tests/mesh/test_mesh_protocols.py +++ b/tests/mesh/test_mesh_protocols.py @@ -2,17 +2,20 @@ from opengeodeweb_viewer.rpc.mesh.mesh_protocols import VtkMeshView from tests.conftest import ServerMonitor +# Local constants +mesh_id = "12345678901234567890123456789012" + def test_register_mesh( server: ServerMonitor, dataset_factory: Callable[..., str] ) -> None: dataset_factory( - id="123456789", viewable_file="hat.vtp", viewer_elements_type="polygons" + id=mesh_id, viewable_file="hat.vtp", viewer_elements_type="polygons" ) server.call( VtkMeshView.mesh_prefix + VtkMeshView.mesh_schemas_dict["register"]["rpc"], - [{"id": "123456789", "name": "hat.vtp"}], + [{"id": mesh_id, "name": "hat.vtp"}], ) assert server.compare_image("mesh/register.jpeg") == True @@ -24,7 +27,7 @@ def test_deregister_mesh( server.call( VtkMeshView.mesh_prefix + VtkMeshView.mesh_schemas_dict["deregister"]["rpc"], - [{"id": "123456789"}], + [{"id": mesh_id}], ) assert server.compare_image("mesh/deregister.jpeg") == True @@ -35,7 +38,7 @@ def test_visibility(server: ServerMonitor, dataset_factory: Callable[..., str]) server.call( VtkMeshView.mesh_prefix + VtkMeshView.mesh_schemas_dict["visibility"]["rpc"], - [{"id": "123456789", "visibility": False}], + [{"id": mesh_id, "visibility": False}], ) assert server.compare_image("mesh/visibility.jpeg") == True @@ -47,7 +50,7 @@ def test_color(server: ServerMonitor, dataset_factory: Callable[..., str]) -> No VtkMeshView.mesh_prefix + VtkMeshView.mesh_schemas_dict["color"]["rpc"], [ { - "id": "123456789", + "id": mesh_id, "color": {"red": 50, "green": 2, "blue": 250, "alpha": 1.0}, } ], @@ -70,7 +73,7 @@ def test_apply_textures( + VtkMeshView.mesh_schemas_dict["apply_textures"]["rpc"], [ { - "id": "123456789", + "id": mesh_id, "textures": [ { "texture_name": "lambert2SG", diff --git a/tests/model/blocks/attribute/polyhedron/test_model_blocks_attribute_polyhedron_protocols.py b/tests/model/blocks/attribute/polyhedron/test_model_blocks_attribute_polyhedron_protocols.py index ec292c96..9ffd7816 100644 --- a/tests/model/blocks/attribute/polyhedron/test_model_blocks_attribute_polyhedron_protocols.py +++ b/tests/model/blocks/attribute/polyhedron/test_model_blocks_attribute_polyhedron_protocols.py @@ -13,7 +13,8 @@ from tests.model.test_model_protocols import test_register_model_cube from tests.conftest import ServerMonitor -model_id = "123456789" +# Local constants +model_id = "12345678901234567890123456789012" def test_blocks_polyhedron_attribute( diff --git a/tests/model/blocks/attribute/vertex/test_model_blocks_attribute_vertex_protocols.py b/tests/model/blocks/attribute/vertex/test_model_blocks_attribute_vertex_protocols.py index 5906802d..3b899a3b 100644 --- a/tests/model/blocks/attribute/vertex/test_model_blocks_attribute_vertex_protocols.py +++ b/tests/model/blocks/attribute/vertex/test_model_blocks_attribute_vertex_protocols.py @@ -13,7 +13,8 @@ from tests.model.test_model_protocols import test_register_model_cube from tests.conftest import ServerMonitor -model_id = "123456789" +# Local constants +model_id = "12345678901234567890123456789012" def test_blocks_vertex_attribute( diff --git a/tests/model/blocks/test_model_blocks_protocols.py b/tests/model/blocks/test_model_blocks_protocols.py index 9b824fd5..c9393a0e 100644 --- a/tests/model/blocks/test_model_blocks_protocols.py +++ b/tests/model/blocks/test_model_blocks_protocols.py @@ -5,11 +5,15 @@ from opengeodeweb_viewer.rpc.model.blocks.model_blocks_protocols import ( VtkModelBlocksView, ) +from opengeodeweb_viewer.rpc.viewer.viewer_protocols import VtkViewerView # Local application imports from tests.model.test_model_protocols import test_register_model_cube from tests.conftest import ServerMonitor +# Local constants +model_id = "12345678901234567890123456789012" + def test_blocks_polyhedra_visibility( server: ServerMonitor, dataset_factory: Callable[..., str] @@ -22,7 +26,7 @@ def test_blocks_polyhedra_visibility( + VtkModelBlocksView.model_blocks_schemas_dict["visibility"]["rpc"], [ { - "id": "123456789", + "id": model_id, "block_ids": list(range(1, 50)), "visibility": False, } @@ -36,7 +40,7 @@ def test_blocks_polyhedra_visibility( + VtkModelBlocksView.model_blocks_schemas_dict["visibility"]["rpc"], [ { - "id": "123456789", + "id": model_id, "block_ids": list(range(48, 50)), "visibility": True, } @@ -57,7 +61,7 @@ def test_blocks_polyhedra_color( + VtkModelBlocksView.model_blocks_schemas_dict["color"]["rpc"], [ { - "id": "123456789", + "id": model_id, "block_ids": list(range(48, 50)), "color_mode": "constant", "color": {"red": 255, "green": 0, "blue": 0, "alpha": 1.0}, @@ -65,3 +69,27 @@ def test_blocks_polyhedra_color( ], ) assert server.compare_image("model/blocks/color.jpeg") == True + + +def test_blocks_clipping_plane( + server: ServerMonitor, dataset_factory: Callable[..., str] +) -> None: + + test_register_model_cube(server, dataset_factory) + + server.call( + VtkViewerView.viewer_prefix + + VtkViewerView.viewer_schemas_dict["clipping_planes"]["rpc"], + [ + { + "ids": [model_id], + "planes": [ + { + "origin": [5.0, 5.0, 5.0], + "normal": [1.0, 1.0, 1.0], + } + ], + } + ], + ) + assert server.compare_image("model/blocks/clipping_plane.jpeg") == True diff --git a/tests/model/corners/attribute/vertex/test_model_corners_attribute_vertex_protocols.py b/tests/model/corners/attribute/vertex/test_model_corners_attribute_vertex_protocols.py index 6f0ded94..e047dc17 100644 --- a/tests/model/corners/attribute/vertex/test_model_corners_attribute_vertex_protocols.py +++ b/tests/model/corners/attribute/vertex/test_model_corners_attribute_vertex_protocols.py @@ -13,7 +13,8 @@ from tests.model.test_model_protocols import test_register_model_cube from tests.conftest import ServerMonitor -model_id = "123456789" +# Local constants +model_id = "12345678901234567890123456789012" def test_corners_vertex_attribute( diff --git a/tests/model/corners/test_model_corners_protocols.py b/tests/model/corners/test_model_corners_protocols.py index f19ea28e..eaef6704 100644 --- a/tests/model/corners/test_model_corners_protocols.py +++ b/tests/model/corners/test_model_corners_protocols.py @@ -10,6 +10,9 @@ from tests.model.test_model_protocols import test_register_model_cube from tests.conftest import ServerMonitor +# Local constants +model_id = "12345678901234567890123456789012" + def test_corners_points_visibility( server: ServerMonitor, dataset_factory: Callable[..., str] @@ -22,7 +25,7 @@ def test_corners_points_visibility( + VtkModelCornersView.model_corners_schemas_dict["visibility"]["rpc"], [ { - "id": "123456789", + "id": model_id, "block_ids": list(range(1, 50)), "visibility": False, } @@ -35,7 +38,7 @@ def test_corners_points_visibility( + VtkModelCornersView.model_corners_schemas_dict["visibility"]["rpc"], [ { - "id": "123456789", + "id": model_id, "block_ids": list(range(1, 13)), "visibility": True, } @@ -55,7 +58,7 @@ def test_corners_points_color( + VtkModelCornersView.model_corners_schemas_dict["color"]["rpc"], [ { - "id": "123456789", + "id": model_id, "block_ids": list(range(1, 13)), "color_mode": "constant", "color": {"red": 255, "green": 0, "blue": 0, "alpha": 1.0}, @@ -74,6 +77,6 @@ def test_corners_points_random_color( server.call( VtkModelCornersView.model_corners_prefix + VtkModelCornersView.model_corners_schemas_dict["color"]["rpc"], - [{"id": "123456789", "block_ids": list(range(1, 13)), "color_mode": "random"}], + [{"id": model_id, "block_ids": list(range(1, 13)), "color_mode": "random"}], ) assert server.compare_image("model/corners/random_color.jpeg") == True diff --git a/tests/model/edges/test_model_edges_protocols.py b/tests/model/edges/test_model_edges_protocols.py index f10dbc48..a9584124 100644 --- a/tests/model/edges/test_model_edges_protocols.py +++ b/tests/model/edges/test_model_edges_protocols.py @@ -10,6 +10,9 @@ from tests.model.test_model_protocols import test_register_model from tests.conftest import ServerMonitor +# Local constants +model_id = "12345678901234567890123456789012" + def test_edges_visibility( server: ServerMonitor, dataset_factory: Callable[..., str] @@ -20,6 +23,6 @@ def test_edges_visibility( server.call( VtkModelEdgesView.model_edges_prefix + VtkModelEdgesView.model_edges_schemas_dict["visibility"]["rpc"], - [{"id": "123456789", "visibility": True}], + [{"id": model_id, "visibility": True}], ) assert server.compare_image("model/edges/visibility.jpeg") == True diff --git a/tests/model/lines/attribute/edge/test_model_lines_attribute_edge_protocols.py b/tests/model/lines/attribute/edge/test_model_lines_attribute_edge_protocols.py index 76b99fef..e1a6f417 100644 --- a/tests/model/lines/attribute/edge/test_model_lines_attribute_edge_protocols.py +++ b/tests/model/lines/attribute/edge/test_model_lines_attribute_edge_protocols.py @@ -13,7 +13,8 @@ from tests.model.test_model_protocols import test_register_model_cube from tests.conftest import ServerMonitor -model_id = "123456789" +# Local constants +model_id = "12345678901234567890123456789012" def test_lines_edge_attribute( diff --git a/tests/model/lines/attribute/vertex/test_model_lines_attribute_vertex_protocols.py b/tests/model/lines/attribute/vertex/test_model_lines_attribute_vertex_protocols.py index c84cd74c..004a91f0 100644 --- a/tests/model/lines/attribute/vertex/test_model_lines_attribute_vertex_protocols.py +++ b/tests/model/lines/attribute/vertex/test_model_lines_attribute_vertex_protocols.py @@ -13,7 +13,8 @@ from tests.model.test_model_protocols import test_register_model_cube from tests.conftest import ServerMonitor -model_id = "123456789" +# Local constants +model_id = "12345678901234567890123456789012" def test_lines_vertex_attribute( diff --git a/tests/model/lines/test_model_lines_protocols.py b/tests/model/lines/test_model_lines_protocols.py index d06ef1a7..3f2bdacf 100644 --- a/tests/model/lines/test_model_lines_protocols.py +++ b/tests/model/lines/test_model_lines_protocols.py @@ -5,11 +5,15 @@ from opengeodeweb_viewer.rpc.model.lines.model_lines_protocols import ( VtkModelLinesView, ) +from opengeodeweb_viewer.rpc.viewer.viewer_protocols import VtkViewerView # Local application imports from tests.model.test_model_protocols import test_register_model_cube from tests.conftest import ServerMonitor +# Local constants +model_id = "12345678901234567890123456789012" + def test_lines_edges_visibility( server: ServerMonitor, dataset_factory: Callable[..., str] @@ -22,7 +26,7 @@ def test_lines_edges_visibility( + VtkModelLinesView.model_lines_schemas_dict["visibility"]["rpc"], [ { - "id": "123456789", + "id": model_id, "block_ids": list(range(1, 50)), "visibility": False, } @@ -35,7 +39,7 @@ def test_lines_edges_visibility( + VtkModelLinesView.model_lines_schemas_dict["visibility"]["rpc"], [ { - "id": "123456789", + "id": model_id, "block_ids": list(range(14, 35)), "visibility": True, } @@ -55,7 +59,7 @@ def test_lines_edges_color( + VtkModelLinesView.model_lines_schemas_dict["color"]["rpc"], [ { - "id": "123456789", + "id": model_id, "block_ids": list(range(14, 35)), "color_mode": "constant", "color": {"red": 255, "green": 0, "blue": 0, "alpha": 0.5}, @@ -63,3 +67,27 @@ def test_lines_edges_color( ], ) assert server.compare_image("model/lines/color.jpeg") == True + + +def test_lines_clipping_plane( + server: ServerMonitor, dataset_factory: Callable[..., str] +) -> None: + + test_lines_edges_visibility(server, dataset_factory) + + server.call( + VtkViewerView.viewer_prefix + + VtkViewerView.viewer_schemas_dict["clipping_planes"]["rpc"], + [ + { + "ids": [model_id], + "planes": [ + { + "origin": [5.0, 5.0, 5.0], + "normal": [1.0, 1.0, 1.0], + } + ], + } + ], + ) + assert server.compare_image("model/lines/clipping_plane.jpeg") == True diff --git a/tests/model/points/test_model_points_protocols.py b/tests/model/points/test_model_points_protocols.py index 95b7eac0..d3f81c17 100644 --- a/tests/model/points/test_model_points_protocols.py +++ b/tests/model/points/test_model_points_protocols.py @@ -10,6 +10,9 @@ from tests.model.test_model_protocols import test_register_model from tests.conftest import ServerMonitor +# Local constants +model_id = "12345678901234567890123456789012" + def test_points_visibility( server: ServerMonitor, dataset_factory: Callable[..., str] @@ -20,7 +23,7 @@ def test_points_visibility( server.call( VtkModelPointsView.model_points_prefix + VtkModelPointsView.model_points_schemas_dict["visibility"]["rpc"], - [{"id": "123456789", "visibility": True}], + [{"id": model_id, "visibility": True}], ) assert server.compare_image("model/points/visibility.jpeg") == True @@ -34,6 +37,6 @@ def test_points_size( server.call( VtkModelPointsView.model_points_prefix + VtkModelPointsView.model_points_schemas_dict["size"]["rpc"], - [{"id": "123456789", "size": 20}], + [{"id": model_id, "size": 20}], ) assert server.compare_image("model/points/size.jpeg") == True diff --git a/tests/model/surfaces/attribute/polygon/test_model_surfaces_attribute_polygon_protocols.py b/tests/model/surfaces/attribute/polygon/test_model_surfaces_attribute_polygon_protocols.py index 7a1ddf33..807f6997 100644 --- a/tests/model/surfaces/attribute/polygon/test_model_surfaces_attribute_polygon_protocols.py +++ b/tests/model/surfaces/attribute/polygon/test_model_surfaces_attribute_polygon_protocols.py @@ -18,7 +18,8 @@ # Local application imports from tests.conftest import ServerMonitor -model_id = "123456789" +# Local constants +model_id = "12345678901234567890123456789012" def add_polygon_attribute_to_cube(model_id: str) -> None: diff --git a/tests/model/surfaces/attribute/vertex/test_model_surfaces_attribute_vertex_protocols.py b/tests/model/surfaces/attribute/vertex/test_model_surfaces_attribute_vertex_protocols.py index 7e6d1c0a..5d1b5e6b 100644 --- a/tests/model/surfaces/attribute/vertex/test_model_surfaces_attribute_vertex_protocols.py +++ b/tests/model/surfaces/attribute/vertex/test_model_surfaces_attribute_vertex_protocols.py @@ -13,7 +13,8 @@ from tests.model.test_model_protocols import test_register_model_cube from tests.conftest import ServerMonitor -model_id = "123456789" +# Local constants +model_id = "12345678901234567890123456789012" def test_surfaces_vertex_attribute( diff --git a/tests/model/surfaces/test_model_surfaces_protocols.py b/tests/model/surfaces/test_model_surfaces_protocols.py index 4edead99..af74bca4 100644 --- a/tests/model/surfaces/test_model_surfaces_protocols.py +++ b/tests/model/surfaces/test_model_surfaces_protocols.py @@ -5,11 +5,15 @@ from opengeodeweb_viewer.rpc.model.surfaces.model_surfaces_protocols import ( VtkModelSurfacesView, ) +from opengeodeweb_viewer.rpc.viewer.viewer_protocols import VtkViewerView # Local application imports from tests.model.test_model_protocols import test_register_model_cube from tests.conftest import ServerMonitor +# Local constants +model_id = "12345678901234567890123456789012" + def test_surfaces_polygons_visibility( server: ServerMonitor, dataset_factory: Callable[..., str] @@ -22,7 +26,7 @@ def test_surfaces_polygons_visibility( + VtkModelSurfacesView.model_surfaces_schemas_dict["visibility"]["rpc"], [ { - "id": "123456789", + "id": model_id, "block_ids": list(range(1, 50)), "visibility": False, } @@ -35,8 +39,8 @@ def test_surfaces_polygons_visibility( + VtkModelSurfacesView.model_surfaces_schemas_dict["visibility"]["rpc"], [ { - "id": "123456789", - "block_ids": list(range(36, 49)), + "id": model_id, + "block_ids": list(range(36, 47)), "visibility": True, } ], @@ -56,8 +60,8 @@ def test_surfaces_polygons_color( + VtkModelSurfacesView.model_surfaces_schemas_dict["color"]["rpc"], [ { - "id": "123456789", - "block_ids": list(range(36, 49)), + "id": model_id, + "block_ids": list(range(36, 47)), "color_mode": "constant", "color": {"red": 255, "green": 0, "blue": 0, "alpha": 0.5}, } @@ -75,6 +79,30 @@ def test_surfaces_polygons_random_color( server.call( VtkModelSurfacesView.model_surfaces_prefix + VtkModelSurfacesView.model_surfaces_schemas_dict["color"]["rpc"], - [{"id": "123456789", "block_ids": list(range(36, 49)), "color_mode": "random"}], + [{"id": model_id, "block_ids": list(range(36, 47)), "color_mode": "random"}], ) assert server.compare_image("model/surfaces/random_color.jpeg") == True + + +def test_surfaces_clipping_plane( + server: ServerMonitor, dataset_factory: Callable[..., str] +) -> None: + + test_surfaces_polygons_visibility(server, dataset_factory) + + server.call( + VtkViewerView.viewer_prefix + + VtkViewerView.viewer_schemas_dict["clipping_planes"]["rpc"], + [ + { + "ids": [model_id], + "planes": [ + { + "origin": [5.0, 5.0, 5.0], + "normal": [1.0, 1.0, 1.0], + } + ], + } + ], + ) + assert server.compare_image("model/surfaces/clipping_plane.jpeg") == True diff --git a/tests/model/test_model_protocols.py b/tests/model/test_model_protocols.py index 6eebc86b..323074b5 100644 --- a/tests/model/test_model_protocols.py +++ b/tests/model/test_model_protocols.py @@ -2,15 +2,18 @@ from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView from tests.conftest import ServerMonitor +# Local constants +model_id = "12345678901234567890123456789012" + def test_register_model( server: ServerMonitor, dataset_factory: Callable[..., str] ) -> None: - dataset_factory(id="123456789", viewable_file="CrossSection.vtm") + dataset_factory(id=model_id, viewable_file="CrossSection.vtm") server.call( VtkModelView.model_prefix + VtkModelView.model_schemas_dict["register"]["rpc"], - [{"id": "123456789", "name": "cube.vtm"}], + [{"id": model_id, "name": "cube.vtm"}], ) assert server.compare_image("model/register.jpeg") == True @@ -19,10 +22,10 @@ def test_register_model_cube( server: ServerMonitor, dataset_factory: Callable[..., str] ) -> None: - dataset_factory(id="123456789", viewable_file="cube.vtm") + dataset_factory(id=model_id, viewable_file="cube.vtm") server.call( VtkModelView.model_prefix + VtkModelView.model_schemas_dict["register"]["rpc"], - [{"id": "123456789", "name": "cube.vtm"}], + [{"id": model_id, "name": "cube.vtm"}], ) assert server.compare_image("model/cube_register.jpeg") == True @@ -36,7 +39,7 @@ def test_visibility_model( server.call( VtkModelView.model_prefix + VtkModelView.model_schemas_dict["visibility"]["rpc"], - [{"id": "123456789", "visibility": False}], + [{"id": model_id, "visibility": False}], ) assert server.compare_image("model/visibility.jpeg") == True @@ -50,7 +53,7 @@ def test_deregister_model( server.call( VtkModelView.model_prefix + VtkModelView.model_schemas_dict["deregister"]["rpc"], - [{"id": "123456789"}], + [{"id": model_id}], ) assert server.compare_image("model/deregister.jpeg") == True @@ -62,7 +65,7 @@ def test_get_blocks_bounds( test_register_model(server, dataset_factory) rpc = VtkModelView.model_prefix + "get_blocks_bounds" - server.call(rpc, [{"id": "123456789", "block_ids": [2]}]) + server.call(rpc, [{"id": "12345678901234567890123456789012", "block_ids": [2]}]) response = server.get_response() while isinstance(response, bytes) or response.get("id") != f"rpc:{rpc}": diff --git a/tests/test_viewer_protocols.py b/tests/test_viewer_protocols.py index 7ebcb0df..14d6fca4 100644 --- a/tests/test_viewer_protocols.py +++ b/tests/test_viewer_protocols.py @@ -12,6 +12,9 @@ from tests.mesh.test_mesh_protocols import test_register_mesh from tests.conftest import ServerMonitor +# Local constants +mesh_id = "12345678901234567890123456789012" + def test_reset_visualization(server: ServerMonitor) -> None: server.call( @@ -342,11 +345,11 @@ def test_combined_scaling_and_grid( ) assert server.compare_image("viewer/reset_visualization.jpeg") == True dataset_factory( - id="123456789", viewable_file="hat.vtp", viewer_elements_type="polygons" + id=mesh_id, viewable_file="hat.vtp", viewer_elements_type="polygons" ) server.call( VtkMeshView.mesh_prefix + VtkMeshView.mesh_schemas_dict["register"]["rpc"], - [{"id": "123456789", "name": "hat.vtp"}], + [{"id": mesh_id, "name": "hat.vtp"}], ) assert server.compare_image("viewer/register_hat.jpeg") == True server.call( @@ -361,3 +364,25 @@ def test_combined_scaling_and_grid( [{"z_scale": 2.5}], ) assert server.compare_image("viewer/combined_scaling_and_grid.jpeg") == True + + +def test_clipping_planes( + server: ServerMonitor, dataset_factory: Callable[..., str] +) -> None: + test_register_mesh(server, dataset_factory) + + server.call( + VtkViewerView.viewer_prefix + + VtkViewerView.viewer_schemas_dict["clipping_planes"]["rpc"], + [ + { + "ids": [mesh_id], + "planes": [ + { + "origin": [0.0, 0.0, 0.0], + "normal": [1.0, 0.0, 0.0], + } + ], + } + ], + )