From 7d24d037d5fbe9b6731a75626dc584e74a9c7e41 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Wed, 15 Apr 2026 15:56:12 +0200 Subject: [PATCH 01/13] feat(modelComponentOptions): color RPC to set random and constant colors for model components category and specific model components --- opengeodeweb_viewer_schemas.json | 36 ++++++++++++-- .../model/blocks/model_blocks_protocols.py | 25 ++++++++-- .../rpc/model/blocks/schemas/color.json | 47 +++++-------------- .../rpc/model/blocks/schemas/color.py | 9 +++- .../model/corners/model_corners_protocols.py | 25 ++++++++-- .../rpc/model/corners/schemas/color.json | 47 +++++-------------- .../rpc/model/corners/schemas/color.py | 9 +++- .../rpc/model/lines/model_lines_protocols.py | 25 ++++++++-- .../rpc/model/lines/schemas/color.json | 47 +++++-------------- .../rpc/model/lines/schemas/color.py | 9 +++- .../rpc/model/model_protocols.py | 9 ++++ .../surfaces/model_surfaces_protocols.py | 25 ++++++++-- .../rpc/model/surfaces/schemas/color.json | 47 +++++-------------- .../rpc/model/surfaces/schemas/color.py | 9 +++- src/opengeodeweb_viewer/utils_functions.py | 27 +++++++++++ src/opengeodeweb_viewer/vtk_protocol.py | 1 + 16 files changed, 237 insertions(+), 160 deletions(-) diff --git a/opengeodeweb_viewer_schemas.json b/opengeodeweb_viewer_schemas.json index 47ffb9db..426c79ec 100644 --- a/opengeodeweb_viewer_schemas.json +++ b/opengeodeweb_viewer_schemas.json @@ -1183,6 +1183,13 @@ }, "minItems": 1 }, + "color_mode": { + "type": "string", + "enum": [ + "constant", + "random" + ] + }, "color": { "type": "object", "properties": { @@ -1219,7 +1226,7 @@ "required": [ "id", "block_ids", - "color" + "color_mode" ], "additionalProperties": false } @@ -1268,6 +1275,13 @@ }, "minItems": 1 }, + "color_mode": { + "type": "string", + "enum": [ + "constant", + "random" + ] + }, "color": { "type": "object", "properties": { @@ -1304,7 +1318,7 @@ "required": [ "id", "block_ids", - "color" + "color_mode" ], "additionalProperties": false } @@ -1374,6 +1388,13 @@ }, "minItems": 1 }, + "color_mode": { + "type": "string", + "enum": [ + "constant", + "random" + ] + }, "color": { "type": "object", "properties": { @@ -1410,7 +1431,7 @@ "required": [ "id", "block_ids", - "color" + "color_mode" ], "additionalProperties": false } @@ -1548,6 +1569,13 @@ }, "minItems": 1 }, + "color_mode": { + "type": "string", + "enum": [ + "constant", + "random" + ] + }, "color": { "type": "object", "properties": { @@ -1584,7 +1612,7 @@ "required": [ "id", "block_ids", - "color" + "color_mode" ], "additionalProperties": false }, diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py b/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py index 692e9ec3..0f7a068d 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py @@ -4,11 +4,13 @@ # Third party imports from wslink import register as exportRpc # type: ignore from opengeodeweb_microservice.schemas import get_schemas_dict +from vtkmodules.vtkRenderingCore import vtkCompositePolyDataMapper # Local application imports from opengeodeweb_viewer.utils_functions import ( validate_schema, RpcParams, + deterministic_color, ) from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView from . import schemas @@ -34,12 +36,29 @@ def setModelBlocksPolyhedraVisibility(self, rpc_params: RpcParams) -> None: self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_blocks_prefix + model_blocks_schemas_dict["color"]["rpc"]) - def setModelBlocksPolyhedraColor(self, rpc_params: RpcParams) -> None: + def setModelBlocksColor(self, rpc_params: RpcParams) -> None: validate_schema( rpc_params, self.model_blocks_schemas_dict["color"], self.model_blocks_prefix, ) params = schemas.Color.from_dict(rpc_params) - color = params.color - self.SetBlocksColor(params.id, params.block_ids, color.r, color.g, color.b) + pipeline = self.get_vtk_pipeline(params.id) + mapper = pipeline.mapper + if not isinstance(mapper, vtkCompositePolyDataMapper): + return + attr = mapper.GetCompositeDataDisplayAttributes() + for block_id in params.block_ids: + block_ds = pipeline.blockDataSets[block_id] + if params.color_mode == schemas.ColorMode.RANDOM: + geode_id = pipeline.blockGeodeIds[block_id] + r, g, b = deterministic_color(geode_id) + attr.SetBlockColor(block_ds, [r, g, b]) + elif params.color is not None: + r, g, b = ( + params.color.r / 255, + params.color.g / 255, + params.color.b / 255, + ) + attr.SetBlockColor(block_ds, [r, g, b]) + mapper.Modified() \ No newline at end of file diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.json b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.json index a775e915..0d7c3543 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.json +++ b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.json @@ -8,48 +8,25 @@ }, "block_ids": { "type": "array", - "items": { - "type": "integer" - }, + "items": { "type": "integer" }, "minItems": 1 }, + "color_mode": { + "type": "string", + "enum": ["constant", "random"] + }, "color": { "type": "object", "properties": { - "r": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "g": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "b": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "a": { - "type": "number", - "minimum": 0, - "maximum": 1, - "default": 1 - } + "r": { "type": "integer", "minimum": 0, "maximum": 255 }, + "g": { "type": "integer", "minimum": 0, "maximum": 255 }, + "b": { "type": "integer", "minimum": 0, "maximum": 255 }, + "a": { "type": "number", "minimum": 0, "maximum": 1, "default": 1 } }, - "required": [ - "r", - "g", - "b" - ], + "required": ["r", "g", "b"], "additionalProperties": false } }, - "required": [ - "id", - "block_ids", - "color" - ], + "required": ["id", "block_ids", "color_mode"], "additionalProperties": false -} \ No newline at end of file +} diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py index 9763bc1c..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py @@ -1,6 +1,7 @@ from dataclasses_json import DataClassJsonMixin from dataclasses import dataclass from typing import Optional, List +from enum import Enum @dataclass @@ -14,11 +15,17 @@ def __post_init__(self) -> None: a: Optional[float] = None +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + @dataclass class Color(DataClassJsonMixin): def __post_init__(self) -> None: print(self, flush=True) block_ids: List[int] - color: ColorClass + color_mode: ColorMode id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py b/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py index ef376891..02f96a22 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py @@ -4,11 +4,13 @@ # Third party imports from wslink import register as exportRpc # type: ignore from opengeodeweb_microservice.schemas import get_schemas_dict +from vtkmodules.vtkRenderingCore import vtkCompositePolyDataMapper # Local application imports from opengeodeweb_viewer.utils_functions import ( validate_schema, RpcParams, + deterministic_color, ) from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView from . import schemas @@ -34,12 +36,29 @@ def setModelCornersPointsVisibility(self, rpc_params: RpcParams) -> None: self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_corners_prefix + model_corners_schemas_dict["color"]["rpc"]) - def setModelCornersPointsColor(self, rpc_params: RpcParams) -> None: + def setModelCornersColor(self, rpc_params: RpcParams) -> None: validate_schema( rpc_params, self.model_corners_schemas_dict["color"], self.model_corners_prefix, ) params = schemas.Color.from_dict(rpc_params) - color = params.color - self.SetBlocksColor(params.id, params.block_ids, color.r, color.g, color.b) + pipeline = self.get_vtk_pipeline(params.id) + mapper = pipeline.mapper + if not isinstance(mapper, vtkCompositePolyDataMapper): + return + attr = mapper.GetCompositeDataDisplayAttributes() + for block_id in params.block_ids: + block_ds = pipeline.blockDataSets[block_id] + if params.color_mode == schemas.ColorMode.RANDOM: + geode_id = pipeline.blockGeodeIds[block_id] + r, g, b = deterministic_color(geode_id) + attr.SetBlockColor(block_ds, [r, g, b]) + elif params.color is not None: + r, g, b = ( + params.color.r / 255, + params.color.g / 255, + params.color.b / 255, + ) + attr.SetBlockColor(block_ds, [r, g, b]) + mapper.Modified() diff --git a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.json b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.json index a775e915..0d7c3543 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.json +++ b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.json @@ -8,48 +8,25 @@ }, "block_ids": { "type": "array", - "items": { - "type": "integer" - }, + "items": { "type": "integer" }, "minItems": 1 }, + "color_mode": { + "type": "string", + "enum": ["constant", "random"] + }, "color": { "type": "object", "properties": { - "r": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "g": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "b": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "a": { - "type": "number", - "minimum": 0, - "maximum": 1, - "default": 1 - } + "r": { "type": "integer", "minimum": 0, "maximum": 255 }, + "g": { "type": "integer", "minimum": 0, "maximum": 255 }, + "b": { "type": "integer", "minimum": 0, "maximum": 255 }, + "a": { "type": "number", "minimum": 0, "maximum": 1, "default": 1 } }, - "required": [ - "r", - "g", - "b" - ], + "required": ["r", "g", "b"], "additionalProperties": false } }, - "required": [ - "id", - "block_ids", - "color" - ], + "required": ["id", "block_ids", "color_mode"], "additionalProperties": false -} \ No newline at end of file +} diff --git a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py index 9763bc1c..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py @@ -1,6 +1,7 @@ from dataclasses_json import DataClassJsonMixin from dataclasses import dataclass from typing import Optional, List +from enum import Enum @dataclass @@ -14,11 +15,17 @@ def __post_init__(self) -> None: a: Optional[float] = None +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + @dataclass class Color(DataClassJsonMixin): def __post_init__(self) -> None: print(self, flush=True) block_ids: List[int] - color: ColorClass + color_mode: ColorMode id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py b/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py index 60c11925..231d8e85 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py @@ -4,11 +4,13 @@ # Third party imports from wslink import register as exportRpc # type: ignore from opengeodeweb_microservice.schemas import get_schemas_dict +from vtkmodules.vtkRenderingCore import vtkCompositePolyDataMapper # Local application imports from opengeodeweb_viewer.utils_functions import ( validate_schema, RpcParams, + deterministic_color, ) from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView from . import schemas @@ -34,12 +36,29 @@ def setModelLinesEdgesVisibility(self, rpc_params: RpcParams) -> None: self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_lines_prefix + model_lines_schemas_dict["color"]["rpc"]) - def setModelLinesEdgesColor(self, rpc_params: RpcParams) -> None: + def setModelLinesColor(self, rpc_params: RpcParams) -> None: validate_schema( rpc_params, self.model_lines_schemas_dict["color"], self.model_lines_prefix, ) params = schemas.Color.from_dict(rpc_params) - color = params.color - self.SetBlocksColor(params.id, params.block_ids, color.r, color.g, color.b) + pipeline = self.get_vtk_pipeline(params.id) + mapper = pipeline.mapper + if not isinstance(mapper, vtkCompositePolyDataMapper): + return + attr = mapper.GetCompositeDataDisplayAttributes() + for block_id in params.block_ids: + block_ds = pipeline.blockDataSets[block_id] + if params.color_mode == schemas.ColorMode.RANDOM: + geode_id = pipeline.blockGeodeIds[block_id] + r, g, b = deterministic_color(geode_id) + attr.SetBlockColor(block_ds, [r, g, b]) + elif params.color is not None: + r, g, b = ( + params.color.r / 255, + params.color.g / 255, + params.color.b / 255, + ) + attr.SetBlockColor(block_ds, [r, g, b]) + mapper.Modified() \ No newline at end of file diff --git a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.json b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.json index a775e915..0d7c3543 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.json +++ b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.json @@ -8,48 +8,25 @@ }, "block_ids": { "type": "array", - "items": { - "type": "integer" - }, + "items": { "type": "integer" }, "minItems": 1 }, + "color_mode": { + "type": "string", + "enum": ["constant", "random"] + }, "color": { "type": "object", "properties": { - "r": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "g": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "b": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "a": { - "type": "number", - "minimum": 0, - "maximum": 1, - "default": 1 - } + "r": { "type": "integer", "minimum": 0, "maximum": 255 }, + "g": { "type": "integer", "minimum": 0, "maximum": 255 }, + "b": { "type": "integer", "minimum": 0, "maximum": 255 }, + "a": { "type": "number", "minimum": 0, "maximum": 1, "default": 1 } }, - "required": [ - "r", - "g", - "b" - ], + "required": ["r", "g", "b"], "additionalProperties": false } }, - "required": [ - "id", - "block_ids", - "color" - ], + "required": ["id", "block_ids", "color_mode"], "additionalProperties": false -} \ No newline at end of file +} diff --git a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py index 9763bc1c..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py @@ -1,6 +1,7 @@ from dataclasses_json import DataClassJsonMixin from dataclasses import dataclass from typing import Optional, List +from enum import Enum @dataclass @@ -14,11 +15,17 @@ def __post_init__(self) -> None: a: Optional[float] = None +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + @dataclass class Color(DataClassJsonMixin): def __post_init__(self) -> None: print(self, flush=True) block_ids: List[int] - color: ColorClass + color_mode: ColorMode id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index 6ca47947..3547721c 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -2,6 +2,9 @@ import os # Third party imports +from vtkmodules.vtkCommonDataModel import ( + vtkCompositeDataSet, +) from vtkmodules.vtkRenderingCore import ( vtkCompositeDataDisplayAttributes, vtkCompositePolyDataMapper, @@ -59,7 +62,13 @@ def registerModel(self, rpc_params: RpcParams) -> None: flat_index = iterator.GetCurrentFlatIndex() while flat_index > len(data.blockDataSets): data.blockDataSets.append(None) + data.blockGeodeIds.append(None) data.blockDataSets.append(block) + meta = iterator.GetCurrentMetaData() + name = None + if meta and meta.Has(vtkCompositeDataSet.NAME()): + name = meta.Get(vtkCompositeDataSet.NAME()) + data.blockGeodeIds.append(name) iterator.GoToNextItem() self.registerObject(data_id, file_name, data) except Exception as e: diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py b/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py index aaa3a818..c498b5ba 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py @@ -4,11 +4,13 @@ # Third party imports from wslink import register as exportRpc # type: ignore from opengeodeweb_microservice.schemas import get_schemas_dict +from vtkmodules.vtkRenderingCore import vtkCompositePolyDataMapper # Local application imports from opengeodeweb_viewer.utils_functions import ( validate_schema, RpcParams, + deterministic_color, ) from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView from . import schemas @@ -34,12 +36,29 @@ def setModelSurfacesPolygonsVisibility(self, rpc_params: RpcParams) -> None: self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_surfaces_prefix + model_surfaces_schemas_dict["color"]["rpc"]) - def setModelSurfacesPolygonsCOlor(self, rpc_params: RpcParams) -> None: + def setModelSurfacesColor(self, rpc_params: RpcParams) -> None: validate_schema( rpc_params, self.model_surfaces_schemas_dict["color"], self.model_surfaces_prefix, ) params = schemas.Color.from_dict(rpc_params) - color = params.color - self.SetBlocksColor(params.id, params.block_ids, color.r, color.g, color.b) + pipeline = self.get_vtk_pipeline(params.id) + mapper = pipeline.mapper + if not isinstance(mapper, vtkCompositePolyDataMapper): + return + attr = mapper.GetCompositeDataDisplayAttributes() + for block_id in params.block_ids: + block_ds = pipeline.blockDataSets[block_id] + if params.color_mode == schemas.ColorMode.RANDOM: + geode_id = pipeline.blockGeodeIds[block_id] + r, g, b = deterministic_color(geode_id) + attr.SetBlockColor(block_ds, [r, g, b]) + elif params.color is not None: + r, g, b = ( + params.color.r / 255, + params.color.g / 255, + params.color.b / 255, + ) + attr.SetBlockColor(block_ds, [r, g, b]) + mapper.Modified() \ No newline at end of file diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.json b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.json index a775e915..0d7c3543 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.json +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.json @@ -8,48 +8,25 @@ }, "block_ids": { "type": "array", - "items": { - "type": "integer" - }, + "items": { "type": "integer" }, "minItems": 1 }, + "color_mode": { + "type": "string", + "enum": ["constant", "random"] + }, "color": { "type": "object", "properties": { - "r": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "g": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "b": { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "a": { - "type": "number", - "minimum": 0, - "maximum": 1, - "default": 1 - } + "r": { "type": "integer", "minimum": 0, "maximum": 255 }, + "g": { "type": "integer", "minimum": 0, "maximum": 255 }, + "b": { "type": "integer", "minimum": 0, "maximum": 255 }, + "a": { "type": "number", "minimum": 0, "maximum": 1, "default": 1 } }, - "required": [ - "r", - "g", - "b" - ], + "required": ["r", "g", "b"], "additionalProperties": false } }, - "required": [ - "id", - "block_ids", - "color" - ], + "required": ["id", "block_ids", "color_mode"], "additionalProperties": false -} \ No newline at end of file +} diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py index 9763bc1c..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py @@ -1,6 +1,7 @@ from dataclasses_json import DataClassJsonMixin from dataclasses import dataclass from typing import Optional, List +from enum import Enum @dataclass @@ -14,11 +15,17 @@ def __post_init__(self) -> None: a: Optional[float] = None +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + @dataclass class Color(DataClassJsonMixin): def __post_init__(self) -> None: print(self, flush=True) block_ids: List[int] - color: ColorClass + color_mode: ColorMode id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/utils_functions.py b/src/opengeodeweb_viewer/utils_functions.py index f2c468de..564fd37f 100644 --- a/src/opengeodeweb_viewer/utils_functions.py +++ b/src/opengeodeweb_viewer/utils_functions.py @@ -2,6 +2,7 @@ # Third party imports import fastjsonschema # type: ignore +import math from opengeodeweb_microservice.schemas import SchemaDict @@ -25,3 +26,29 @@ def validate_schema( "description": e.message, } ) + +def deterministic_color(identifier: str) -> tuple[float, float, float]: + CIRCLE_DEGREES = 360 + HASH_PRIME = 31 + DEGREES_PER_STEP = 30 + STEPS_COUNT = 12 + BASE_LIGHTNESS = 0.5 + VIBRANCY_RANGE = 0.35 + MIRROR_MAX = 9 + PHASE_GREEN = 8 + + if not identifier: + return (128 / 255, 128 / 255, 128 / 255) + + h = 0 + for ch in identifier: + h = ord(ch) + h * HASH_PRIME + + hue = abs(h % CIRCLE_DEGREES) + + def component(phase: int) -> float: + step = (phase + hue / DEGREES_PER_STEP) % STEPS_COUNT + intensity = BASE_LIGHTNESS - VIBRANCY_RANGE * max(min(step - 3, MIRROR_MAX - step, 1), -1) + return round(255 * intensity) / 255 + + return (component(0), component(PHASE_GREEN), component(4)) \ No newline at end of file diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index 4fb092a0..0955f33c 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -43,6 +43,7 @@ class VtkPipeline: filter: vtkAlgorithm | None = None actor: vtkActor = field(default_factory=vtkActor) blockDataSets: list[vtkDataObject | None] = field(default_factory=list) + blockGeodeIds: list[str | None] = field(default_factory=list) class VtkTypingMixin: From 4ca30edb34e8dbdfc278abbc8ddf6c05df6e0e61 Mon Sep 17 00:00:00 2001 From: MaxNumerique <144453705+MaxNumerique@users.noreply.github.com> Date: Wed, 15 Apr 2026 15:08:40 +0000 Subject: [PATCH 02/13] Apply prepare changes --- requirements.txt | 1 - .../rpc/model/blocks/model_blocks_protocols.py | 2 +- .../rpc/model/lines/model_lines_protocols.py | 2 +- .../rpc/model/surfaces/model_surfaces_protocols.py | 2 +- src/opengeodeweb_viewer/utils_functions.py | 7 +++++-- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/requirements.txt b/requirements.txt index 5f1e9fc5..16407b43 100644 --- a/requirements.txt +++ b/requirements.txt @@ -61,4 +61,3 @@ wslink==1.12.4 yarl>=1 # via aiohttp -opengeodeweb-microservice==1.*,>=1.1.2rc1 diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py b/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py index 0f7a068d..6f0b457f 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py @@ -61,4 +61,4 @@ def setModelBlocksColor(self, rpc_params: RpcParams) -> None: params.color.b / 255, ) attr.SetBlockColor(block_ds, [r, g, b]) - mapper.Modified() \ No newline at end of file + mapper.Modified() diff --git a/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py b/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py index 231d8e85..f4bd4fc5 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py @@ -61,4 +61,4 @@ def setModelLinesColor(self, rpc_params: RpcParams) -> None: params.color.b / 255, ) attr.SetBlockColor(block_ds, [r, g, b]) - mapper.Modified() \ No newline at end of file + mapper.Modified() diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py b/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py index c498b5ba..40020856 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py @@ -61,4 +61,4 @@ def setModelSurfacesColor(self, rpc_params: RpcParams) -> None: params.color.b / 255, ) attr.SetBlockColor(block_ds, [r, g, b]) - mapper.Modified() \ No newline at end of file + mapper.Modified() diff --git a/src/opengeodeweb_viewer/utils_functions.py b/src/opengeodeweb_viewer/utils_functions.py index 564fd37f..cf7697fe 100644 --- a/src/opengeodeweb_viewer/utils_functions.py +++ b/src/opengeodeweb_viewer/utils_functions.py @@ -27,6 +27,7 @@ def validate_schema( } ) + def deterministic_color(identifier: str) -> tuple[float, float, float]: CIRCLE_DEGREES = 360 HASH_PRIME = 31 @@ -48,7 +49,9 @@ def deterministic_color(identifier: str) -> tuple[float, float, float]: def component(phase: int) -> float: step = (phase + hue / DEGREES_PER_STEP) % STEPS_COUNT - intensity = BASE_LIGHTNESS - VIBRANCY_RANGE * max(min(step - 3, MIRROR_MAX - step, 1), -1) + intensity = BASE_LIGHTNESS - VIBRANCY_RANGE * max( + min(step - 3, MIRROR_MAX - step, 1), -1 + ) return round(255 * intensity) / 255 - return (component(0), component(PHASE_GREEN), component(4)) \ No newline at end of file + return (component(0), component(PHASE_GREEN), component(4)) From 545d6bead4c1ba7aad9a8f98dcf2e7ea1a7e9289 Mon Sep 17 00:00:00 2001 From: MaxNumerique <144453705+MaxNumerique@users.noreply.github.com> Date: Thu, 16 Apr 2026 08:02:57 +0000 Subject: [PATCH 03/13] Apply prepare changes --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3e6ddf7f..16407b43 100644 --- a/requirements.txt +++ b/requirements.txt @@ -61,4 +61,3 @@ wslink==1.12.4 yarl>=1 # via aiohttp -opengeodeweb-microservice==1.*,>=1.1.2 From 6b3742744b86c8a6618ffc971ac8583b28526441 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Thu, 16 Apr 2026 13:58:41 +0200 Subject: [PATCH 04/13] refacto --- .../model/blocks/model_blocks_protocols.py | 30 ++---------- .../model/corners/model_corners_protocols.py | 30 ++---------- .../rpc/model/lines/model_lines_protocols.py | 30 ++---------- .../rpc/model/model_protocols.py | 46 +++++++++++++++++-- .../surfaces/model_surfaces_protocols.py | 30 ++---------- src/opengeodeweb_viewer/vtk_protocol.py | 2 +- 6 files changed, 63 insertions(+), 105 deletions(-) diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py b/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py index 6f0b457f..2738d770 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py @@ -4,14 +4,9 @@ # Third party imports from wslink import register as exportRpc # type: ignore from opengeodeweb_microservice.schemas import get_schemas_dict -from vtkmodules.vtkRenderingCore import vtkCompositePolyDataMapper # Local application imports -from opengeodeweb_viewer.utils_functions import ( - validate_schema, - RpcParams, - deterministic_color, -) +from opengeodeweb_viewer.utils_functions import validate_schema, RpcParams from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView from . import schemas @@ -36,7 +31,7 @@ def setModelBlocksPolyhedraVisibility(self, rpc_params: RpcParams) -> None: self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_blocks_prefix + model_blocks_schemas_dict["color"]["rpc"]) - def setModelBlocksColor(self, rpc_params: RpcParams) -> None: + def setModelBlocksColor(self, rpc_params: RpcParams) -> list[dict]: validate_schema( rpc_params, self.model_blocks_schemas_dict["color"], @@ -44,21 +39,6 @@ def setModelBlocksColor(self, rpc_params: RpcParams) -> None: ) params = schemas.Color.from_dict(rpc_params) pipeline = self.get_vtk_pipeline(params.id) - mapper = pipeline.mapper - if not isinstance(mapper, vtkCompositePolyDataMapper): - return - attr = mapper.GetCompositeDataDisplayAttributes() - for block_id in params.block_ids: - block_ds = pipeline.blockDataSets[block_id] - if params.color_mode == schemas.ColorMode.RANDOM: - geode_id = pipeline.blockGeodeIds[block_id] - r, g, b = deterministic_color(geode_id) - attr.SetBlockColor(block_ds, [r, g, b]) - elif params.color is not None: - r, g, b = ( - params.color.r / 255, - params.color.g / 255, - params.color.b / 255, - ) - attr.SetBlockColor(block_ds, [r, g, b]) - mapper.Modified() + return self.apply_color( + pipeline, params.block_ids, params.color_mode.value, params.color + ) diff --git a/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py b/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py index 02f96a22..4b1bf498 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py @@ -4,14 +4,9 @@ # Third party imports from wslink import register as exportRpc # type: ignore from opengeodeweb_microservice.schemas import get_schemas_dict -from vtkmodules.vtkRenderingCore import vtkCompositePolyDataMapper # Local application imports -from opengeodeweb_viewer.utils_functions import ( - validate_schema, - RpcParams, - deterministic_color, -) +from opengeodeweb_viewer.utils_functions import validate_schema, RpcParams from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView from . import schemas @@ -36,7 +31,7 @@ def setModelCornersPointsVisibility(self, rpc_params: RpcParams) -> None: self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_corners_prefix + model_corners_schemas_dict["color"]["rpc"]) - def setModelCornersColor(self, rpc_params: RpcParams) -> None: + def setModelCornersColor(self, rpc_params: RpcParams) -> list[dict]: validate_schema( rpc_params, self.model_corners_schemas_dict["color"], @@ -44,21 +39,6 @@ def setModelCornersColor(self, rpc_params: RpcParams) -> None: ) params = schemas.Color.from_dict(rpc_params) pipeline = self.get_vtk_pipeline(params.id) - mapper = pipeline.mapper - if not isinstance(mapper, vtkCompositePolyDataMapper): - return - attr = mapper.GetCompositeDataDisplayAttributes() - for block_id in params.block_ids: - block_ds = pipeline.blockDataSets[block_id] - if params.color_mode == schemas.ColorMode.RANDOM: - geode_id = pipeline.blockGeodeIds[block_id] - r, g, b = deterministic_color(geode_id) - attr.SetBlockColor(block_ds, [r, g, b]) - elif params.color is not None: - r, g, b = ( - params.color.r / 255, - params.color.g / 255, - params.color.b / 255, - ) - attr.SetBlockColor(block_ds, [r, g, b]) - mapper.Modified() + return self.apply_color( + pipeline, params.block_ids, params.color_mode.value, params.color + ) diff --git a/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py b/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py index f4bd4fc5..b32a7e4d 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py @@ -4,14 +4,9 @@ # Third party imports from wslink import register as exportRpc # type: ignore from opengeodeweb_microservice.schemas import get_schemas_dict -from vtkmodules.vtkRenderingCore import vtkCompositePolyDataMapper # Local application imports -from opengeodeweb_viewer.utils_functions import ( - validate_schema, - RpcParams, - deterministic_color, -) +from opengeodeweb_viewer.utils_functions import validate_schema, RpcParams from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView from . import schemas @@ -36,7 +31,7 @@ def setModelLinesEdgesVisibility(self, rpc_params: RpcParams) -> None: self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_lines_prefix + model_lines_schemas_dict["color"]["rpc"]) - def setModelLinesColor(self, rpc_params: RpcParams) -> None: + def setModelLinesColor(self, rpc_params: RpcParams) -> list[dict]: validate_schema( rpc_params, self.model_lines_schemas_dict["color"], @@ -44,21 +39,6 @@ def setModelLinesColor(self, rpc_params: RpcParams) -> None: ) params = schemas.Color.from_dict(rpc_params) pipeline = self.get_vtk_pipeline(params.id) - mapper = pipeline.mapper - if not isinstance(mapper, vtkCompositePolyDataMapper): - return - attr = mapper.GetCompositeDataDisplayAttributes() - for block_id in params.block_ids: - block_ds = pipeline.blockDataSets[block_id] - if params.color_mode == schemas.ColorMode.RANDOM: - geode_id = pipeline.blockGeodeIds[block_id] - r, g, b = deterministic_color(geode_id) - attr.SetBlockColor(block_ds, [r, g, b]) - elif params.color is not None: - r, g, b = ( - params.color.r / 255, - params.color.g / 255, - params.color.b / 255, - ) - attr.SetBlockColor(block_ds, [r, g, b]) - mapper.Modified() + return self.apply_color( + pipeline, params.block_ids, params.color_mode.value, params.color + ) diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index 3547721c..09ad7409 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -18,6 +18,7 @@ from opengeodeweb_viewer.utils_functions import ( validate_schema, RpcParams, + deterministic_color, ) from opengeodeweb_viewer.object.object_methods import VtkObjectView from opengeodeweb_viewer.vtk_protocol import VtkPipeline @@ -33,6 +34,45 @@ class VtkModelView(VtkObjectView): def __init__(self) -> None: super().__init__() + def apply_color( + self, + pipeline: VtkPipeline, + block_ids: list[int], + color_mode: str, + color=None, + ) -> list[dict]: + mapper = pipeline.mapper + if not isinstance(mapper, vtkCompositePolyDataMapper): + return [] + attr = mapper.GetCompositeDataDisplayAttributes() + colors: list[dict] = [] + for block_id in block_ids: + block_ds = pipeline.blockDataSets[block_id] + if color_mode == "random": + geode_id = pipeline.blockGeodeIds[block_id] + r, g, b = deterministic_color(str(geode_id)) + attr.SetBlockColor(block_ds, [r, g, b]) + colors.append( + { + "viewer_id": block_id, + "geode_id": str(geode_id), + "color": { + "r": round(r * 255), + "g": round(g * 255), + "b": round(b * 255), + }, + } + ) + elif color is not None: + r, g, b = ( + color.r / 255, + color.g / 255, + color.b / 255, + ) + attr.SetBlockColor(block_ds, [r, g, b]) + mapper.Modified() + return colors + @exportRpc(model_prefix + model_schemas_dict["register"]["rpc"]) def registerModel(self, rpc_params: RpcParams) -> None: validate_schema( @@ -62,12 +102,10 @@ def registerModel(self, rpc_params: RpcParams) -> None: flat_index = iterator.GetCurrentFlatIndex() while flat_index > len(data.blockDataSets): data.blockDataSets.append(None) - data.blockGeodeIds.append(None) + data.blockGeodeIds.append("") data.blockDataSets.append(block) meta = iterator.GetCurrentMetaData() - name = None - if meta and meta.Has(vtkCompositeDataSet.NAME()): - name = meta.Get(vtkCompositeDataSet.NAME()) + name = meta.Get(vtkCompositeDataSet.NAME()) data.blockGeodeIds.append(name) iterator.GoToNextItem() self.registerObject(data_id, file_name, data) diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py b/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py index 40020856..bb5259c5 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py @@ -4,14 +4,9 @@ # Third party imports from wslink import register as exportRpc # type: ignore from opengeodeweb_microservice.schemas import get_schemas_dict -from vtkmodules.vtkRenderingCore import vtkCompositePolyDataMapper # Local application imports -from opengeodeweb_viewer.utils_functions import ( - validate_schema, - RpcParams, - deterministic_color, -) +from opengeodeweb_viewer.utils_functions import validate_schema, RpcParams from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView from . import schemas @@ -36,7 +31,7 @@ def setModelSurfacesPolygonsVisibility(self, rpc_params: RpcParams) -> None: self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_surfaces_prefix + model_surfaces_schemas_dict["color"]["rpc"]) - def setModelSurfacesColor(self, rpc_params: RpcParams) -> None: + def setModelSurfacesColor(self, rpc_params: RpcParams) -> list[dict]: validate_schema( rpc_params, self.model_surfaces_schemas_dict["color"], @@ -44,21 +39,6 @@ def setModelSurfacesColor(self, rpc_params: RpcParams) -> None: ) params = schemas.Color.from_dict(rpc_params) pipeline = self.get_vtk_pipeline(params.id) - mapper = pipeline.mapper - if not isinstance(mapper, vtkCompositePolyDataMapper): - return - attr = mapper.GetCompositeDataDisplayAttributes() - for block_id in params.block_ids: - block_ds = pipeline.blockDataSets[block_id] - if params.color_mode == schemas.ColorMode.RANDOM: - geode_id = pipeline.blockGeodeIds[block_id] - r, g, b = deterministic_color(geode_id) - attr.SetBlockColor(block_ds, [r, g, b]) - elif params.color is not None: - r, g, b = ( - params.color.r / 255, - params.color.g / 255, - params.color.b / 255, - ) - attr.SetBlockColor(block_ds, [r, g, b]) - mapper.Modified() + return self.apply_color( + pipeline, params.block_ids, params.color_mode.value, params.color + ) diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index af5224a7..59256a97 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -43,7 +43,7 @@ class VtkPipeline: filter: vtkAlgorithm | None = None actor: vtkActor = field(default_factory=vtkActor) blockDataSets: list[vtkDataObject | None] = field(default_factory=list) - blockGeodeIds: list[str | None] = field(default_factory=list) + blockGeodeIds: list[str] = field(default_factory=list) class VtkTypingMixin: From a87f69b5cb62322b77e81dd091e2bbff86664055 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Thu, 16 Apr 2026 15:15:39 +0200 Subject: [PATCH 05/13] test mypy --- .../model/blocks/model_blocks_protocols.py | 4 +- .../rpc/model/blocks/schemas/color.py | 32 +-------------- .../model/corners/model_corners_protocols.py | 4 +- .../rpc/model/corners/schemas/color.py | 32 +-------------- .../rpc/model/lines/model_lines_protocols.py | 4 +- .../rpc/model/lines/schemas/color.py | 32 +-------------- .../rpc/model/model_protocols.py | 8 ++-- .../rpc/model/schemas/__init__.py | 1 + .../rpc/model/schemas/color.py | 40 +++++++++++++++++++ .../surfaces/model_surfaces_protocols.py | 4 +- .../rpc/model/surfaces/schemas/color.py | 32 +-------------- 11 files changed, 58 insertions(+), 135 deletions(-) create mode 100644 src/opengeodeweb_viewer/rpc/model/schemas/color.py diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py b/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py index 2738d770..fb59d603 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py @@ -7,7 +7,7 @@ # Local application imports from opengeodeweb_viewer.utils_functions import validate_schema, RpcParams -from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView +from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView, ColorResult from . import schemas @@ -31,7 +31,7 @@ def setModelBlocksPolyhedraVisibility(self, rpc_params: RpcParams) -> None: self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_blocks_prefix + model_blocks_schemas_dict["color"]["rpc"]) - def setModelBlocksColor(self, rpc_params: RpcParams) -> list[dict]: + def setModelBlocksColor(self, rpc_params: RpcParams) -> list[ColorResult]: validate_schema( rpc_params, self.model_blocks_schemas_dict["color"], diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py index 8a0e135c..c34c5da9 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py @@ -1,31 +1 @@ -from dataclasses_json import DataClassJsonMixin -from dataclasses import dataclass -from typing import Optional, List -from enum import Enum - - -@dataclass -class ColorClass(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - b: int - g: int - r: int - a: Optional[float] = None - - -class ColorMode(Enum): - CONSTANT = "constant" - RANDOM = "random" - - -@dataclass -class Color(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - block_ids: List[int] - color_mode: ColorMode - id: str - color: Optional[ColorClass] = None +from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode diff --git a/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py b/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py index 4b1bf498..7e5d0428 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py @@ -7,7 +7,7 @@ # Local application imports from opengeodeweb_viewer.utils_functions import validate_schema, RpcParams -from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView +from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView, ColorResult from . import schemas @@ -31,7 +31,7 @@ def setModelCornersPointsVisibility(self, rpc_params: RpcParams) -> None: self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_corners_prefix + model_corners_schemas_dict["color"]["rpc"]) - def setModelCornersColor(self, rpc_params: RpcParams) -> list[dict]: + def setModelCornersColor(self, rpc_params: RpcParams) -> list[ColorResult]: validate_schema( rpc_params, self.model_corners_schemas_dict["color"], diff --git a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py index 8a0e135c..c34c5da9 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py @@ -1,31 +1 @@ -from dataclasses_json import DataClassJsonMixin -from dataclasses import dataclass -from typing import Optional, List -from enum import Enum - - -@dataclass -class ColorClass(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - b: int - g: int - r: int - a: Optional[float] = None - - -class ColorMode(Enum): - CONSTANT = "constant" - RANDOM = "random" - - -@dataclass -class Color(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - block_ids: List[int] - color_mode: ColorMode - id: str - color: Optional[ColorClass] = None +from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode diff --git a/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py b/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py index b32a7e4d..a44cecd5 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py @@ -7,7 +7,7 @@ # Local application imports from opengeodeweb_viewer.utils_functions import validate_schema, RpcParams -from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView +from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView, ColorResult from . import schemas @@ -31,7 +31,7 @@ def setModelLinesEdgesVisibility(self, rpc_params: RpcParams) -> None: self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_lines_prefix + model_lines_schemas_dict["color"]["rpc"]) - def setModelLinesColor(self, rpc_params: RpcParams) -> list[dict]: + def setModelLinesColor(self, rpc_params: RpcParams) -> list[ColorResult]: validate_schema( rpc_params, self.model_lines_schemas_dict["color"], diff --git a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py index 8a0e135c..c34c5da9 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py @@ -1,31 +1 @@ -from dataclasses_json import DataClassJsonMixin -from dataclasses import dataclass -from typing import Optional, List -from enum import Enum - - -@dataclass -class ColorClass(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - b: int - g: int - r: int - a: Optional[float] = None - - -class ColorMode(Enum): - CONSTANT = "constant" - RANDOM = "random" - - -@dataclass -class Color(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - block_ids: List[int] - color_mode: ColorMode - id: str - color: Optional[ColorClass] = None +from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index 09ad7409..ea7e01dd 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -22,7 +22,9 @@ ) from opengeodeweb_viewer.object.object_methods import VtkObjectView from opengeodeweb_viewer.vtk_protocol import VtkPipeline +from typing import Optional from . import schemas +from .schemas.color import ColorClass, ColorResult class VtkModelView(VtkObjectView): @@ -39,13 +41,13 @@ def apply_color( pipeline: VtkPipeline, block_ids: list[int], color_mode: str, - color=None, - ) -> list[dict]: + color: Optional[ColorClass] = None, + ) -> list[ColorResult]: mapper = pipeline.mapper if not isinstance(mapper, vtkCompositePolyDataMapper): return [] attr = mapper.GetCompositeDataDisplayAttributes() - colors: list[dict] = [] + colors: list[ColorResult] = [] for block_id in block_ids: block_ds = pipeline.blockDataSets[block_id] if color_mode == "random": diff --git a/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py index a974c1d6..a7ca3f55 100644 --- a/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py +++ b/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py @@ -1,3 +1,4 @@ from .visibility import * from .register import * from .deregister import * +from .color import * diff --git a/src/opengeodeweb_viewer/rpc/model/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/schemas/color.py new file mode 100644 index 00000000..9bf814c7 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/schemas/color.py @@ -0,0 +1,40 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, TypedDict, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None + + +class ColorRGB(TypedDict): + r: int + g: int + b: int + + +class ColorResult(TypedDict): + viewer_id: int + geode_id: str + color: ColorRGB diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py b/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py index bb5259c5..0c761d29 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py @@ -7,7 +7,7 @@ # Local application imports from opengeodeweb_viewer.utils_functions import validate_schema, RpcParams -from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView +from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView, ColorResult from . import schemas @@ -31,7 +31,7 @@ def setModelSurfacesPolygonsVisibility(self, rpc_params: RpcParams) -> None: self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_surfaces_prefix + model_surfaces_schemas_dict["color"]["rpc"]) - def setModelSurfacesColor(self, rpc_params: RpcParams) -> list[dict]: + def setModelSurfacesColor(self, rpc_params: RpcParams) -> list[ColorResult]: validate_schema( rpc_params, self.model_surfaces_schemas_dict["color"], diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py index 8a0e135c..c34c5da9 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py @@ -1,31 +1 @@ -from dataclasses_json import DataClassJsonMixin -from dataclasses import dataclass -from typing import Optional, List -from enum import Enum - - -@dataclass -class ColorClass(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - b: int - g: int - r: int - a: Optional[float] = None - - -class ColorMode(Enum): - CONSTANT = "constant" - RANDOM = "random" - - -@dataclass -class Color(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - block_ids: List[int] - color_mode: ColorMode - id: str - color: Optional[ColorClass] = None +from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode From bb8fe83472d773c1ae3bec7d8fb125a191932f24 Mon Sep 17 00:00:00 2001 From: MaxNumerique <144453705+MaxNumerique@users.noreply.github.com> Date: Thu, 16 Apr 2026 13:16:28 +0000 Subject: [PATCH 06/13] Apply prepare changes --- .../rpc/model/blocks/schemas/color.py | 32 ++++++++++++++- .../rpc/model/corners/schemas/color.py | 32 ++++++++++++++- .../rpc/model/lines/schemas/color.py | 32 ++++++++++++++- .../rpc/model/schemas/__init__.py | 1 - .../rpc/model/schemas/color.py | 40 ------------------- .../rpc/model/surfaces/schemas/color.py | 32 ++++++++++++++- 6 files changed, 124 insertions(+), 45 deletions(-) delete mode 100644 src/opengeodeweb_viewer/rpc/model/schemas/color.py diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py index c34c5da9..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py @@ -1 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py index c34c5da9..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py @@ -1 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py index c34c5da9..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py @@ -1 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py index a7ca3f55..a974c1d6 100644 --- a/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py +++ b/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py @@ -1,4 +1,3 @@ from .visibility import * from .register import * from .deregister import * -from .color import * diff --git a/src/opengeodeweb_viewer/rpc/model/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/schemas/color.py deleted file mode 100644 index 9bf814c7..00000000 --- a/src/opengeodeweb_viewer/rpc/model/schemas/color.py +++ /dev/null @@ -1,40 +0,0 @@ -from dataclasses_json import DataClassJsonMixin -from dataclasses import dataclass -from typing import Optional, TypedDict, List -from enum import Enum - - -@dataclass -class ColorClass(DataClassJsonMixin): - b: int - g: int - r: int - a: Optional[float] = None - - -class ColorMode(Enum): - CONSTANT = "constant" - RANDOM = "random" - - -@dataclass -class Color(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - block_ids: List[int] - color_mode: ColorMode - id: str - color: Optional[ColorClass] = None - - -class ColorRGB(TypedDict): - r: int - g: int - b: int - - -class ColorResult(TypedDict): - viewer_id: int - geode_id: str - color: ColorRGB diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py index c34c5da9..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py @@ -1 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None From 8dd67027e283996a1c025e8356098c0ae076ba8b Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Thu, 16 Apr 2026 15:20:07 +0200 Subject: [PATCH 07/13] schema --- src/opengeodeweb_viewer/rpc/model/model_protocols.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index ea7e01dd..1c39b7e0 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -24,7 +24,10 @@ from opengeodeweb_viewer.vtk_protocol import VtkPipeline from typing import Optional from . import schemas -from .schemas.color import ColorClass, ColorResult +from opengeodeweb_viewer.rpc.model.schemas.color import ( + ColorClass as ColorClass, + ColorResult as ColorResult, +) class VtkModelView(VtkObjectView): From bdfd84fe5e7ec1704640d52318430cc59dc73fcf Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Thu, 16 Apr 2026 15:24:07 +0200 Subject: [PATCH 08/13] mypy --- .../rpc/model/blocks/schemas/color.py | 32 +-------------- .../rpc/model/corners/schemas/color.py | 32 +-------------- .../rpc/model/lines/schemas/color.py | 32 +-------------- .../rpc/model/schemas/__init__.py | 1 + .../rpc/model/schemas/color.py | 40 +++++++++++++++++++ .../rpc/model/surfaces/schemas/color.py | 32 +-------------- 6 files changed, 45 insertions(+), 124 deletions(-) create mode 100644 src/opengeodeweb_viewer/rpc/model/schemas/color.py diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py index 8a0e135c..c34c5da9 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py @@ -1,31 +1 @@ -from dataclasses_json import DataClassJsonMixin -from dataclasses import dataclass -from typing import Optional, List -from enum import Enum - - -@dataclass -class ColorClass(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - b: int - g: int - r: int - a: Optional[float] = None - - -class ColorMode(Enum): - CONSTANT = "constant" - RANDOM = "random" - - -@dataclass -class Color(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - block_ids: List[int] - color_mode: ColorMode - id: str - color: Optional[ColorClass] = None +from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode diff --git a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py index 8a0e135c..c34c5da9 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py @@ -1,31 +1 @@ -from dataclasses_json import DataClassJsonMixin -from dataclasses import dataclass -from typing import Optional, List -from enum import Enum - - -@dataclass -class ColorClass(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - b: int - g: int - r: int - a: Optional[float] = None - - -class ColorMode(Enum): - CONSTANT = "constant" - RANDOM = "random" - - -@dataclass -class Color(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - block_ids: List[int] - color_mode: ColorMode - id: str - color: Optional[ColorClass] = None +from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode diff --git a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py index 8a0e135c..c34c5da9 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py @@ -1,31 +1 @@ -from dataclasses_json import DataClassJsonMixin -from dataclasses import dataclass -from typing import Optional, List -from enum import Enum - - -@dataclass -class ColorClass(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - b: int - g: int - r: int - a: Optional[float] = None - - -class ColorMode(Enum): - CONSTANT = "constant" - RANDOM = "random" - - -@dataclass -class Color(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - block_ids: List[int] - color_mode: ColorMode - id: str - color: Optional[ColorClass] = None +from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode diff --git a/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py index a974c1d6..a7ca3f55 100644 --- a/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py +++ b/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py @@ -1,3 +1,4 @@ from .visibility import * from .register import * from .deregister import * +from .color import * diff --git a/src/opengeodeweb_viewer/rpc/model/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/schemas/color.py new file mode 100644 index 00000000..9bf814c7 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/schemas/color.py @@ -0,0 +1,40 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, TypedDict, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None + + +class ColorRGB(TypedDict): + r: int + g: int + b: int + + +class ColorResult(TypedDict): + viewer_id: int + geode_id: str + color: ColorRGB diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py index 8a0e135c..c34c5da9 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py @@ -1,31 +1 @@ -from dataclasses_json import DataClassJsonMixin -from dataclasses import dataclass -from typing import Optional, List -from enum import Enum - - -@dataclass -class ColorClass(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - b: int - g: int - r: int - a: Optional[float] = None - - -class ColorMode(Enum): - CONSTANT = "constant" - RANDOM = "random" - - -@dataclass -class Color(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - block_ids: List[int] - color_mode: ColorMode - id: str - color: Optional[ColorClass] = None +from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode From 23a142c4735ccdb98f647aad4e4497ab22f607b7 Mon Sep 17 00:00:00 2001 From: MaxNumerique <144453705+MaxNumerique@users.noreply.github.com> Date: Thu, 16 Apr 2026 13:25:18 +0000 Subject: [PATCH 09/13] Apply prepare changes --- .../rpc/model/blocks/schemas/color.py | 32 ++++++++++++++- .../rpc/model/corners/schemas/color.py | 32 ++++++++++++++- .../rpc/model/lines/schemas/color.py | 32 ++++++++++++++- .../rpc/model/schemas/__init__.py | 1 - .../rpc/model/schemas/color.py | 40 ------------------- .../rpc/model/surfaces/schemas/color.py | 32 ++++++++++++++- 6 files changed, 124 insertions(+), 45 deletions(-) delete mode 100644 src/opengeodeweb_viewer/rpc/model/schemas/color.py diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py index c34c5da9..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py @@ -1 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py index c34c5da9..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py @@ -1 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py index c34c5da9..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py @@ -1 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py index a7ca3f55..a974c1d6 100644 --- a/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py +++ b/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py @@ -1,4 +1,3 @@ from .visibility import * from .register import * from .deregister import * -from .color import * diff --git a/src/opengeodeweb_viewer/rpc/model/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/schemas/color.py deleted file mode 100644 index 9bf814c7..00000000 --- a/src/opengeodeweb_viewer/rpc/model/schemas/color.py +++ /dev/null @@ -1,40 +0,0 @@ -from dataclasses_json import DataClassJsonMixin -from dataclasses import dataclass -from typing import Optional, TypedDict, List -from enum import Enum - - -@dataclass -class ColorClass(DataClassJsonMixin): - b: int - g: int - r: int - a: Optional[float] = None - - -class ColorMode(Enum): - CONSTANT = "constant" - RANDOM = "random" - - -@dataclass -class Color(DataClassJsonMixin): - def __post_init__(self) -> None: - print(self, flush=True) - - block_ids: List[int] - color_mode: ColorMode - id: str - color: Optional[ColorClass] = None - - -class ColorRGB(TypedDict): - r: int - g: int - b: int - - -class ColorResult(TypedDict): - viewer_id: int - geode_id: str - color: ColorRGB diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py index c34c5da9..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py @@ -1 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None From 38dfeac063e9826480545139dc821498fb96f6a2 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Thu, 16 Apr 2026 15:28:16 +0200 Subject: [PATCH 10/13] mypy --- src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py | 6 +++++- src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py | 6 +++++- src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py | 6 +++++- src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py | 6 +++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py index c34c5da9..7f24883b 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py @@ -1 +1,5 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode +from opengeodeweb_viewer.rpc.model.schemas.color import ( + Color as Color, + ColorClass as ColorClass, + ColorMode as ColorMode, +) diff --git a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py index c34c5da9..7f24883b 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py @@ -1 +1,5 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode +from opengeodeweb_viewer.rpc.model.schemas.color import ( + Color as Color, + ColorClass as ColorClass, + ColorMode as ColorMode, +) diff --git a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py index c34c5da9..7f24883b 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py @@ -1 +1,5 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode +from opengeodeweb_viewer.rpc.model.schemas.color import ( + Color as Color, + ColorClass as ColorClass, + ColorMode as ColorMode, +) diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py index c34c5da9..7f24883b 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py @@ -1 +1,5 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import Color, ColorClass, ColorMode +from opengeodeweb_viewer.rpc.model.schemas.color import ( + Color as Color, + ColorClass as ColorClass, + ColorMode as ColorMode, +) From a145210a1c4817304c2276d35a135556e837fb29 Mon Sep 17 00:00:00 2001 From: MaxNumerique <144453705+MaxNumerique@users.noreply.github.com> Date: Thu, 16 Apr 2026 13:32:12 +0000 Subject: [PATCH 11/13] Apply prepare changes --- .../rpc/model/blocks/schemas/color.py | 36 ++++++++++++++++--- .../rpc/model/corners/schemas/color.py | 36 ++++++++++++++++--- .../rpc/model/lines/schemas/color.py | 36 ++++++++++++++++--- .../rpc/model/surfaces/schemas/color.py | 36 ++++++++++++++++--- 4 files changed, 124 insertions(+), 20 deletions(-) diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py index 7f24883b..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py @@ -1,5 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import ( - Color as Color, - ColorClass as ColorClass, - ColorMode as ColorMode, -) +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py index 7f24883b..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py @@ -1,5 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import ( - Color as Color, - ColorClass as ColorClass, - ColorMode as ColorMode, -) +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py index 7f24883b..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py @@ -1,5 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import ( - Color as Color, - ColorClass as ColorClass, - ColorMode as ColorMode, -) +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py index 7f24883b..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py @@ -1,5 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import ( - Color as Color, - ColorClass as ColorClass, - ColorMode as ColorMode, -) +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None From 4194cd2688429752eee2292e4532c388e6529371 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Thu, 16 Apr 2026 15:33:38 +0200 Subject: [PATCH 12/13] revert --- .../rpc/model/blocks/schemas/color.py | 36 ++++++++++++++++--- .../rpc/model/corners/schemas/color.py | 36 ++++++++++++++++--- .../rpc/model/lines/schemas/color.py | 36 ++++++++++++++++--- .../rpc/model/model_protocols.py | 25 +++++++++---- .../rpc/model/surfaces/schemas/color.py | 36 ++++++++++++++++--- 5 files changed, 143 insertions(+), 26 deletions(-) diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py index 7f24883b..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py @@ -1,5 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import ( - Color as Color, - ColorClass as ColorClass, - ColorMode as ColorMode, -) +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py index 7f24883b..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py @@ -1,5 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import ( - Color as Color, - ColorClass as ColorClass, - ColorMode as ColorMode, -) +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py index 7f24883b..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py @@ -1,5 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import ( - Color as Color, - ColorClass as ColorClass, - ColorMode as ColorMode, -) +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index 1c39b7e0..84422cbe 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -22,12 +22,25 @@ ) from opengeodeweb_viewer.object.object_methods import VtkObjectView from opengeodeweb_viewer.vtk_protocol import VtkPipeline -from typing import Optional +from typing import Optional, List, TypedDict, Protocol from . import schemas -from opengeodeweb_viewer.rpc.model.schemas.color import ( - ColorClass as ColorClass, - ColorResult as ColorResult, -) + +class ColorProtocol(Protocol): + r: int + g: int + b: int + + +class ColorRGB(TypedDict): + r: int + g: int + b: int + + +class ColorResult(TypedDict): + viewer_id: int + geode_id: str + color: ColorRGB class VtkModelView(VtkObjectView): @@ -44,7 +57,7 @@ def apply_color( pipeline: VtkPipeline, block_ids: list[int], color_mode: str, - color: Optional[ColorClass] = None, + color: Optional[ColorProtocol] = None, ) -> list[ColorResult]: mapper = pipeline.mapper if not isinstance(mapper, vtkCompositePolyDataMapper): diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py index 7f24883b..8a0e135c 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py @@ -1,5 +1,31 @@ -from opengeodeweb_viewer.rpc.model.schemas.color import ( - Color as Color, - ColorClass as ColorClass, - ColorMode as ColorMode, -) +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List +from enum import Enum + + +@dataclass +class ColorClass(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + b: int + g: int + r: int + a: Optional[float] = None + + +class ColorMode(Enum): + CONSTANT = "constant" + RANDOM = "random" + + +@dataclass +class Color(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + block_ids: List[int] + color_mode: ColorMode + id: str + color: Optional[ColorClass] = None From f7a54fa37d8c3e8b5e88f5227e48f989203b193a Mon Sep 17 00:00:00 2001 From: MaxNumerique <144453705+MaxNumerique@users.noreply.github.com> Date: Thu, 16 Apr 2026 13:35:21 +0000 Subject: [PATCH 13/13] Apply prepare changes --- src/opengeodeweb_viewer/rpc/model/model_protocols.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index 84422cbe..bdad0f36 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -25,6 +25,7 @@ from typing import Optional, List, TypedDict, Protocol from . import schemas + class ColorProtocol(Protocol): r: int g: int