diff --git a/.gitignore b/.gitignore index 04053a6..ad211f4 100644 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,4 @@ build .coverage* .mypy_cache *.db -tests/tests_output/ -opengeodeweb_viewer_schemas.json \ No newline at end of file +tests/tests_output/ \ No newline at end of file diff --git a/opengeodeweb_viewer_schemas.json b/opengeodeweb_viewer_schemas.json new file mode 100644 index 0000000..c39d37d --- /dev/null +++ b/opengeodeweb_viewer_schemas.json @@ -0,0 +1,1397 @@ +{ + "opengeodeweb_viewer": { + "generic": { + "register": { + "$id": "opengeodeweb_viewer.generic.register", + "rpc": "register", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id" + ], + "additionalProperties": false + }, + "deregister": { + "$id": "opengeodeweb_viewer.generic.deregister", + "rpc": "deregister", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id" + ], + "additionalProperties": false + } + }, + "mesh": { + "edges": { + "width": { + "$id": "opengeodeweb_viewer.mesh.edges.size", + "rpc": "size", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "width": { + "type": "number" + } + }, + "required": [ + "id", + "width" + ], + "additionalProperties": false + }, + "visibility": { + "$id": "opengeodeweb_viewer.mesh.edges.visibility", + "rpc": "visibility", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "visibility": { + "type": "boolean" + } + }, + "required": [ + "id", + "visibility" + ], + "additionalProperties": false + }, + "vertex_attribute": { + "$id": "opengeodeweb_viewer.mesh.edges.vertex_attribute", + "rpc": "vertex_attribute", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "name": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id", + "name" + ], + "additionalProperties": false + }, + "size": { + "$id": "opengeodeweb_viewer.mesh.edges.size", + "rpc": "size", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "size": { + "type": "integer" + } + }, + "required": [ + "id", + "size" + ], + "additionalProperties": false + }, + "color": { + "$id": "opengeodeweb_viewer.mesh.edges.color", + "rpc": "color", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "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 + } + }, + "required": [ + "r", + "g", + "b" + ], + "additionalProperties": false + } + }, + "required": [ + "id", + "color" + ], + "additionalProperties": false + } + }, + "points": { + "visibility": { + "$id": "opengeodeweb_viewer.mesh.points.visibility", + "rpc": "visibility", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "visibility": { + "type": "boolean" + } + }, + "required": [ + "id", + "visibility" + ], + "additionalProperties": false + }, + "vertex_attribute": { + "$id": "opengeodeweb_viewer.mesh.points.vertex_attribute", + "rpc": "vertex_attribute", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "name": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id", + "name" + ], + "additionalProperties": false + }, + "size": { + "$id": "opengeodeweb_viewer.mesh.points.size", + "rpc": "size", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "size": { + "type": "number" + } + }, + "required": [ + "id", + "size" + ], + "additionalProperties": false + }, + "color": { + "$id": "opengeodeweb_viewer.mesh.points.color", + "rpc": "color", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "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 + } + }, + "required": [ + "r", + "g", + "b" + ], + "additionalProperties": false + } + }, + "required": [ + "id", + "color" + ], + "additionalProperties": false + } + }, + "polygons": { + "visibility": { + "$id": "opengeodeweb_viewer.mesh.polygons.visibility", + "rpc": "visibility", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "visibility": { + "type": "boolean" + } + }, + "required": [ + "id", + "visibility" + ], + "additionalProperties": false + }, + "vertex_attribute": { + "$id": "opengeodeweb_viewer.mesh.polygons.vertex_attribute", + "rpc": "vertex_attribute", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "name": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id", + "name" + ], + "additionalProperties": false + }, + "polygon_attribute": { + "$id": "opengeodeweb_viewer.mesh.polygons.polygon_attribute", + "rpc": "polygon_attribute", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "name": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id", + "name" + ], + "additionalProperties": false + }, + "color": { + "$id": "opengeodeweb_viewer.mesh.polygons.color", + "rpc": "color", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "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 + } + }, + "required": [ + "r", + "g", + "b" + ], + "additionalProperties": false + } + }, + "required": [ + "id", + "color" + ], + "additionalProperties": false + } + }, + "polyhedra": { + "visibility": { + "$id": "opengeodeweb_viewer.mesh.polyhedra.visibility", + "rpc": "visibility", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "visibility": { + "type": "boolean" + } + }, + "required": [ + "id", + "visibility" + ], + "additionalProperties": false + }, + "vertex_attribute": { + "$id": "opengeodeweb_viewer.mesh.polyhedra.vertex_attribute", + "rpc": "vertex_attribute", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "name": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id", + "name" + ], + "additionalProperties": false + }, + "polyhedron_attribute": { + "$id": "opengeodeweb_viewer.mesh.polyhedra.polyhedron_attribute", + "rpc": "polyhedron_attribute", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "name": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id", + "name" + ], + "additionalProperties": false + }, + "color": { + "$id": "opengeodeweb_viewer.mesh.polyhedra.color", + "rpc": "color", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "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 + } + }, + "required": [ + "r", + "g", + "b" + ], + "additionalProperties": false + } + }, + "required": [ + "id", + "color" + ], + "additionalProperties": false + } + }, + "visibility": { + "$id": "opengeodeweb_viewer.mesh.visibility", + "rpc": "visibility", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "visibility": { + "type": "boolean" + } + }, + "required": [ + "id", + "visibility" + ], + "additionalProperties": false + }, + "register": { + "$id": "opengeodeweb_viewer.mesh.register", + "rpc": "register", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id" + ], + "additionalProperties": false + }, + "opacity": { + "$id": "opengeodeweb_viewer.mesh.opacity", + "rpc": "opacity", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "opacity": { + "type": "number", + "min": 0, + "max": 1 + } + }, + "required": [ + "id", + "opacity" + ], + "additionalProperties": false + }, + "deregister": { + "$id": "opengeodeweb_viewer.mesh.deregister", + "rpc": "deregister", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id" + ], + "additionalProperties": false + }, + "color": { + "$id": "opengeodeweb_viewer.mesh.color", + "rpc": "color", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "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 + } + }, + "required": [ + "r", + "g", + "b" + ], + "additionalProperties": false + } + }, + "required": [ + "id", + "color" + ], + "additionalProperties": false + }, + "apply_textures": { + "$id": "opengeodeweb_viewer.mesh.apply_textures", + "rpc": "apply_textures", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "textures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "texture_name": { + "type": "string", + "minLength": 1 + }, + "id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "texture_name", + "id" + ], + "additionalProperties": false + }, + "minItems": 1 + } + }, + "required": [ + "id", + "textures" + ], + "additionalProperties": false + } + }, + "model": { + "blocks": { + "visibility": { + "$id": "opengeodeweb_viewer.model.blocks.visibility", + "rpc": "visibility", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "block_ids": { + "type": "array", + "items": { + "type": "integer", + "minLength": 1 + }, + "minItems": 1 + }, + "visibility": { + "type": "boolean" + } + }, + "required": [ + "id", + "block_ids", + "visibility" + ], + "additionalProperties": false + }, + "color": { + "$id": "opengeodeweb_viewer.model.blocks.color", + "rpc": "color", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "block_ids": { + "type": "array", + "items": { + "type": "integer", + "minLength": 1 + }, + "minItems": 1 + }, + "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 + } + }, + "required": [ + "r", + "g", + "b" + ], + "additionalProperties": false + } + }, + "required": [ + "id", + "block_ids", + "color" + ], + "additionalProperties": false + } + }, + "corners": { + "visibility": { + "$id": "opengeodeweb_viewer.model.corners.visibility", + "rpc": "visibility", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "block_ids": { + "type": "array", + "items": { + "type": "integer", + "minLength": 1 + }, + "minItems": 1 + }, + "visibility": { + "type": "boolean" + } + }, + "required": [ + "id", + "block_ids", + "visibility" + ], + "additionalProperties": false + }, + "color": { + "$id": "opengeodeweb_viewer.model.corners.color", + "rpc": "color", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "block_ids": { + "type": "array", + "items": { + "type": "integer", + "minLength": 1 + }, + "minItems": 1 + }, + "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 + } + }, + "required": [ + "r", + "g", + "b" + ], + "additionalProperties": false + } + }, + "required": [ + "id", + "block_ids", + "color" + ], + "additionalProperties": false + } + }, + "edges": { + "visibility": { + "$id": "opengeodeweb_viewer.model.edges.visibility", + "rpc": "visibility", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "visibility": { + "type": "boolean" + } + }, + "required": [ + "id", + "visibility" + ], + "additionalProperties": false + } + }, + "lines": { + "visibility": { + "$id": "opengeodeweb_viewer.model.lines.visibility", + "rpc": "visibility", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "block_ids": { + "type": "array", + "items": { + "type": "integer", + "minLength": 1 + }, + "minItems": 1 + }, + "visibility": { + "type": "boolean" + } + }, + "required": [ + "id", + "block_ids", + "visibility" + ], + "additionalProperties": false + }, + "color": { + "$id": "opengeodeweb_viewer.model.lines.color", + "rpc": "color", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "block_ids": { + "type": "array", + "items": { + "type": "integer", + "minLength": 1 + }, + "minItems": 1 + }, + "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 + } + }, + "required": [ + "r", + "g", + "b" + ], + "additionalProperties": false + } + }, + "required": [ + "id", + "block_ids", + "color" + ], + "additionalProperties": false + } + }, + "points": { + "visibility": { + "$id": "opengeodeweb_viewer.model.points.visibility", + "rpc": "visibility", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "visibility": { + "type": "boolean" + } + }, + "required": [ + "id", + "visibility" + ], + "additionalProperties": false + }, + "size": { + "$id": "opengeodeweb_viewer.model.points.size", + "rpc": "size", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "size": { + "type": "number" + } + }, + "required": [ + "id", + "size" + ], + "additionalProperties": false + } + }, + "visibility": { + "$id": "opengeodeweb_viewer.model.visibility", + "rpc": "visibility", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "visibility": { + "type": "boolean" + } + }, + "required": [ + "id", + "visibility" + ], + "additionalProperties": false + }, + "register": { + "$id": "opengeodeweb_viewer.model.register", + "rpc": "register", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id" + ], + "additionalProperties": false + }, + "deregister": { + "$id": "opengeodeweb_viewer.model.deregister", + "rpc": "deregister", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id" + ], + "additionalProperties": false + }, + "surfaces": { + "visibility": { + "$id": "opengeodeweb_viewer.model.surfaces.visibility", + "rpc": "visibility", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "block_ids": { + "type": "array", + "items": { + "type": "integer", + "minLength": 1 + }, + "minItems": 1 + }, + "visibility": { + "type": "boolean" + } + }, + "required": [ + "id", + "block_ids", + "visibility" + ], + "additionalProperties": false + }, + "color": { + "$id": "opengeodeweb_viewer.model.surfaces.color", + "rpc": "color", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "block_ids": { + "type": "array", + "items": { + "type": "integer", + "minLength": 1 + }, + "minItems": 1 + }, + "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 + } + }, + "required": [ + "r", + "g", + "b" + ], + "additionalProperties": false + } + }, + "required": [ + "id", + "block_ids", + "color" + ], + "additionalProperties": false + }, + "apply_textures": { + "$id": "opengeodeweb_viewer.model.surfaces.apply_textures", + "rpc": "apply_textures", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "textures": { + "type": "array", + "items": { + "type": "object", + "properties": { + "texture_name": { + "type": "string", + "minLength": 1 + }, + "texture_file_name": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "texture_name", + "texture_file_name" + ], + "additionalProperties": false + }, + "minItems": 1 + } + }, + "required": [ + "id", + "textures" + ], + "additionalProperties": false + } + } + }, + "kill": { + "$id": "opengeodeweb_viewer.kill", + "rpc": "kill", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "viewer": { + "update_data": { + "$id": "opengeodeweb_viewer.viewer.update_data", + "rpc": "update_data", + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id" + ], + "additionalProperties": false + }, + "update_camera": { + "$id": "opengeodeweb_viewer.viewer.update_camera", + "rpc": "update_camera", + "type": "object", + "properties": { + "camera_options": { + "type": "object", + "properties": { + "focal_point": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3 + }, + "view_up": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3 + }, + "position": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3 + }, + "view_angle": { + "type": "number" + }, + "clipping_range": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 2, + "maxItems": 2 + } + }, + "required": [ + "focal_point", + "view_up", + "position", + "view_angle", + "clipping_range" + ] + } + }, + "required": [ + "camera_options" + ] + }, + "take_screenshot": { + "$id": "opengeodeweb_viewer.viewer.take_screenshot", + "rpc": "take_screenshot", + "type": "object", + "properties": { + "filename": { + "type": "string", + "minLength": 1 + }, + "output_extension": { + "type": "string", + "minLength": 1, + "enum": [ + "png", + "jpg" + ] + }, + "include_background": { + "type": "boolean" + } + }, + "required": [ + "filename", + "output_extension", + "include_background" + ], + "additionalProperties": false + }, + "set_z_scaling": { + "$id": "opengeodeweb_viewer.viewer.set_z_scaling", + "rpc": "set_z_scaling", + "type": "object", + "properties": { + "z_scale": { + "type": "number", + "minimum": 1 + } + }, + "required": [ + "z_scale" + ], + "additionalProperties": false + }, + "set_background_color": { + "$id": "opengeodeweb_viewer.viewer.set_background_color", + "rpc": "set_background_color", + "type": "object", + "properties": { + "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 + } + }, + "required": [ + "r", + "g", + "b" + ], + "additionalProperties": false + } + }, + "required": [ + "color" + ], + "additionalProperties": false + }, + "reset_visualization": { + "$id": "opengeodeweb_viewer.viewer.reset_visualization", + "rpc": "reset_visualization", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "reset_camera": { + "$id": "opengeodeweb_viewer.viewer.reset_camera", + "rpc": "reset_camera", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "render_now": { + "$id": "opengeodeweb_viewer.viewer.render_now", + "rpc": "render_now", + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "picked_ids": { + "$id": "opengeodeweb_viewer.viewer.picked_ids", + "rpc": "picked_ids", + "type": "object", + "properties": { + "x": { + "type": "number" + }, + "y": { + "type": "number" + }, + "ids": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + } + }, + "required": [ + "x", + "y", + "ids" + ], + "additionalProperties": false + }, + "grid_scale": { + "$id": "opengeodeweb_viewer.viewer.grid_scale", + "rpc": "grid_scale", + "type": "object", + "properties": { + "visibility": { + "type": "boolean" + } + }, + "required": [ + "visibility" + ], + "additionalProperties": false + }, + "get_point_position": { + "$id": "opengeodeweb_viewer.viewer.get_point_position", + "rpc": "get_point_position", + "type": "object", + "properties": { + "x": { + "type": "integer" + }, + "y": { + "type": "integer" + } + }, + "required": [ + "x", + "y" + ], + "additionalProperties": false + }, + "axes": { + "$id": "opengeodeweb_viewer.viewer.axes", + "rpc": "axes", + "type": "object", + "properties": { + "visibility": { + "type": "boolean" + } + }, + "required": [ + "visibility" + ], + "additionalProperties": false + } + } + } +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 28124d6..065674a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -61,4 +61,3 @@ wslink==1.12.4 yarl>=1 # via aiohttp -opengeodeweb-microservice==1.*,>=1.0.5 diff --git a/src/opengeodeweb_viewer/object/object_methods.py b/src/opengeodeweb_viewer/object/object_methods.py index faea2ad..fc71d14 100644 --- a/src/opengeodeweb_viewer/object/object_methods.py +++ b/src/opengeodeweb_viewer/object/object_methods.py @@ -2,10 +2,13 @@ import os # Third party imports -import vtk +from vtkmodules.vtkIOXML import vtkXMLDataReader, vtkXMLImageDataReader +from vtkmodules.vtkCommonExecutionModel import vtkAlgorithm +from vtkmodules.vtkRenderingCore import vtkMapper, vtkActor, vtkTexture +from vtkmodules.vtkCommonDataModel import vtkDataObject # Local application imports -from opengeodeweb_viewer.vtk_protocol import VtkView +from opengeodeweb_viewer.vtk_protocol import VtkView, vtkData class VtkObjectView(VtkView): @@ -16,28 +19,25 @@ def registerObject( self, id: str, file_name: str, - reader: vtk.vtkDataReader, - filter: vtk.vtkAlgorithm | None, - mapper: vtk.vtkMapper, + data: vtkData, ) -> None: - actor = vtk.vtkActor() - self.register_object(id, reader, filter, actor, mapper, {}) - reader.SetFileName(os.path.join(self.DATA_FOLDER_PATH, id, file_name)) - actor.SetMapper(mapper) - mapper.SetColorModeToMapScalars() - mapper.SetResolveCoincidentTopologyLineOffsetParameters(1, -0.1) - mapper.SetResolveCoincidentTopologyPolygonOffsetParameters(2, 0) - mapper.SetResolveCoincidentTopologyPointOffsetParameter(-2) + self.register_object(id, data) + data.reader.SetFileName(os.path.join(self.DATA_FOLDER_PATH, id, file_name)) + data.actor.SetMapper(data.mapper) + data.mapper.SetColorModeToMapScalars() + data.mapper.SetResolveCoincidentTopologyLineOffsetParameters(1, -0.1) + data.mapper.SetResolveCoincidentTopologyPolygonOffsetParameters(2, 0) + data.mapper.SetResolveCoincidentTopologyPointOffsetParameter(-2) renderWindow = self.getView("-1") renderer = renderWindow.GetRenderers().GetFirstRenderer() - renderer.AddActor(actor) + renderer.AddActor(data.actor) renderer.ResetCamera() renderWindow.Render() self.render() def deregisterObject(self, data_id: str) -> None: - actor = self.get_object(data_id)["actor"] + actor = self.get_object(data_id).actor renderWindow = self.getView("-1") renderer = renderWindow.GetRenderers().GetFirstRenderer() renderer.RemoveActor(actor) @@ -45,8 +45,8 @@ def deregisterObject(self, data_id: str) -> None: self.render() def applyTextures(self, data_id: str, textures: list[dict[str, str]]) -> None: - textures_array: list[vtk.vtkTexture] = [] - images_reader_array: list[vtk.vtkXMLImageDataReader] = [] + textures_array: list[vtkTexture] = [] + images_reader_array: list[vtkXMLImageDataReader] = [] data = self.get_object(data_id) mapper = data["mapper"] @@ -61,8 +61,8 @@ def applyTextures(self, data_id: str, textures: list[dict[str, str]]) -> None: id_texture = value["id"] print(f"{texture_name=} {id_texture=}", flush=True) - new_texture = vtk.vtkTexture() - image_reader = vtk.vtkXMLImageDataReader() + new_texture = vtkTexture() + image_reader = vtkXMLImageDataReader() texture_path = self.get_data_file_path(data_id, id_texture) image_reader.SetFileName(texture_path) @@ -70,17 +70,15 @@ def applyTextures(self, data_id: str, textures: list[dict[str, str]]) -> None: polydata_mapper.MapDataArrayToMultiTextureAttribute( shader_texture_name, texture_name, - vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS, + vtkDataObject.FIELD_ASSOCIATION_POINTS, ) if index == 0: new_texture.SetBlendingMode( - vtk.vtkTexture.VTK_TEXTURE_BLENDING_MODE_REPLACE + vtkTexture.VTK_TEXTURE_BLENDING_MODE_REPLACE ) else: - new_texture.SetBlendingMode( - vtk.vtkTexture.VTK_TEXTURE_BLENDING_MODE_ADD - ) + new_texture.SetBlendingMode(vtkTexture.VTK_TEXTURE_BLENDING_MODE_ADD) images_reader_array.append(image_reader) new_texture.SetInputConnection(image_reader.GetOutputPort()) @@ -93,25 +91,25 @@ def applyTextures(self, data_id: str, textures: list[dict[str, str]]) -> None: self.render() def SetVisibility(self, data_id: str, visibility: bool) -> None: - actor = self.get_object(data_id)["actor"] + actor = self.get_object(data_id).actor actor.SetVisibility(visibility) self.render() def SetOpacity(self, data_id: str, opacity: float) -> None: - actor = self.get_object(data_id)["actor"] + actor = self.get_object(data_id).actor actor.GetProperty().SetOpacity(opacity) self.render() def SetColor(self, data_id: str, red: int, green: int, blue: int) -> None: - mapper = self.get_object(data_id)["mapper"] + mapper = self.get_object(data_id).mapper mapper.ScalarVisibilityOff() - actor = self.get_object(data_id)["actor"] + actor = self.get_object(data_id).actor actor.GetProperty().SetColor([red / 255, green / 255, blue / 255]) self.render() def SetEdgesVisibility(self, data_id: str, visibility: bool) -> None: - actor = self.get_object(data_id)["actor"] - max_dimension = self.get_object(data_id)["max_dimension"] + actor = self.get_object(data_id).actor + max_dimension = self.get_object(data_id).max_dimension if max_dimension == "edges": self.SetVisibility(data_id, visibility) else: @@ -119,13 +117,13 @@ def SetEdgesVisibility(self, data_id: str, visibility: bool) -> None: self.render() def SetEdgesWidth(self, data_id: str, width: float) -> None: - actor = self.get_object(data_id)["actor"] + actor = self.get_object(data_id).actor actor.GetProperty().SetEdgeWidth(width) self.render() def SetEdgesColor(self, data_id: str, red: int, green: int, blue: int) -> None: - actor = self.get_object(data_id)["actor"] - max_dimension = self.get_object(data_id)["max_dimension"] + actor = self.get_object(data_id).actor + max_dimension = self.get_object(data_id).max_dimension if max_dimension == "edges": self.SetColor(data_id, red, green, blue) else: @@ -133,8 +131,8 @@ def SetEdgesColor(self, data_id: str, red: int, green: int, blue: int) -> None: self.render() def SetPointsVisibility(self, data_id: str, visibility: bool) -> None: - actor = self.get_object(data_id)["actor"] - max_dimension = self.get_object(data_id)["max_dimension"] + actor = self.get_object(data_id).actor + max_dimension = self.get_object(data_id).max_dimension if max_dimension == "points": self.SetVisibility(data_id, visibility) else: @@ -142,13 +140,13 @@ def SetPointsVisibility(self, data_id: str, visibility: bool) -> None: self.render() def SetPointsSize(self, data_id: str, size: float) -> None: - actor = self.get_object(data_id)["actor"] + actor = self.get_object(data_id).actor actor.GetProperty().SetPointSize(size) self.render() def SetPointsColor(self, data_id: str, red: int, green: int, blue: int) -> None: - actor = self.get_object(data_id)["actor"] - max_dimension = self.get_object(data_id)["max_dimension"] + actor = self.get_object(data_id).actor + max_dimension = self.get_object(data_id).max_dimension if max_dimension == "points": self.SetColor(data_id, red, green, blue) else: @@ -158,7 +156,7 @@ def SetPointsColor(self, data_id: str, red: int, green: int, blue: int) -> None: def SetBlocksVisibility( self, data_id: str, block_ids: list[int], visibility: bool ) -> None: - mapper = self.get_object(data_id)["mapper"] + mapper = self.get_object(data_id).mapper for block_id in block_ids: mapper.SetBlockVisibility(block_id, visibility) self.render() @@ -166,7 +164,7 @@ def SetBlocksVisibility( def SetBlocksColor( self, data_id: str, block_ids: list[int], red: int, green: int, blue: int ) -> None: - mapper = self.get_object(data_id)["mapper"] + mapper = self.get_object(data_id).mapper for block_id in block_ids: mapper.SetBlockColor(block_id, [red / 255, green / 255, blue / 255]) self.render() diff --git a/src/opengeodeweb_viewer/rpc/generic/generic_protocols.py b/src/opengeodeweb_viewer/rpc/generic/generic_protocols.py index 29e8052..f14a9c2 100644 --- a/src/opengeodeweb_viewer/rpc/generic/generic_protocols.py +++ b/src/opengeodeweb_viewer/rpc/generic/generic_protocols.py @@ -2,12 +2,19 @@ import os # Third party imports -from vtk.web import protocols as vtk_protocols -from wslink import register as exportRpc +from vtkmodules.web import protocols as vtk_protocols +from wslink import register as exportRpc # type: ignore +from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports from opengeodeweb_viewer.vtk_protocol import VtkView -from opengeodeweb_viewer.utils_functions import get_schemas_dict, validate_schema +from opengeodeweb_viewer.rpc.mesh.mesh_protocols import VtkMeshView +from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView +from opengeodeweb_viewer.utils_functions import ( + validate_schema, + RpcParams, +) +from . import schemas class VtkGenericView(VtkView): @@ -16,17 +23,20 @@ class VtkGenericView(VtkView): os.path.join(os.path.dirname(__file__), "schemas") ) - def __init__(self, mesh_protocols, model_protocols): + def __init__( + self, mesh_protocols: VtkMeshView, model_protocols: VtkModelView + ) -> None: super().__init__() self.mesh_protocols = mesh_protocols self.model_protocols = model_protocols @exportRpc(generic_prefix + generic_schemas_dict["register"]["rpc"]) - def register(self, params): + def register(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.generic_schemas_dict["register"], self.generic_prefix + rpc_params, self.generic_schemas_dict["register"], self.generic_prefix ) - data_id = str(params["id"]) + params = schemas.Register.from_dict(rpc_params) + data_id = params.id specific_params = {"id": data_id} data = self.get_data(data_id) viewer_object = str(data["viewer_object"]) @@ -36,11 +46,12 @@ def register(self, params): self.model_protocols.registerModel(specific_params) @exportRpc(generic_prefix + generic_schemas_dict["deregister"]["rpc"]) - def deregister(self, params): + def deregister(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.generic_schemas_dict["deregister"], self.generic_prefix + rpc_params, self.generic_schemas_dict["deregister"], self.generic_prefix ) - data_id = str(params["id"]) + params = schemas.Deregister.from_dict(rpc_params) + data_id = params.id specific_params = {"id": data_id} data = self.get_data(data_id) viewer_object = str(data["viewer_object"]) diff --git a/src/opengeodeweb_viewer/rpc/generic/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/generic/schemas/__init__.py new file mode 100644 index 0000000..b10a36f --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/generic/schemas/__init__.py @@ -0,0 +1,2 @@ +from .register import * +from .deregister import * diff --git a/src/opengeodeweb_viewer/rpc/generic/schemas/deregister.py b/src/opengeodeweb_viewer/rpc/generic/schemas/deregister.py new file mode 100644 index 0000000..f9c0aee --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/generic/schemas/deregister.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Deregister(DataClassJsonMixin): + id: str diff --git a/src/opengeodeweb_viewer/rpc/generic/schemas/register.py b/src/opengeodeweb_viewer/rpc/generic/schemas/register.py new file mode 100644 index 0000000..e15e699 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/generic/schemas/register.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Register(DataClassJsonMixin): + id: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/edges/mesh_edges_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/edges/mesh_edges_protocols.py index a2db0f5..1f0f62c 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/edges/mesh_edges_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/edges/mesh_edges_protocols.py @@ -2,11 +2,16 @@ import os # Third party imports -from wslink import register as exportRpc +from wslink import register as exportRpc # type: ignore +from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports -from opengeodeweb_viewer.utils_functions import get_schemas_dict, validate_schema +from opengeodeweb_viewer.utils_functions import ( + validate_schema, + RpcParams, +) from opengeodeweb_viewer.rpc.mesh.mesh_protocols import VtkMeshView +from . import schemas class VtkMeshEdgesView(VtkMeshView): @@ -15,34 +20,32 @@ class VtkMeshEdgesView(VtkMeshView): os.path.join(os.path.dirname(__file__), "schemas") ) - def __init__(self): + def __init__(self) -> None: super().__init__() @exportRpc(mesh_edges_prefix + mesh_edges_schemas_dict["visibility"]["rpc"]) - def setMeshEdgesVisibility(self, params): + def setMeshEdgesVisibility(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.mesh_edges_schemas_dict["visibility"], self.mesh_edges_prefix + rpc_params, + self.mesh_edges_schemas_dict["visibility"], + self.mesh_edges_prefix, ) - id, visibility = params["id"], params["visibility"] - self.SetEdgesVisibility(id, visibility) + params = schemas.Visibility.from_dict(rpc_params) + self.SetEdgesVisibility(params.id, params.visibility) @exportRpc(mesh_edges_prefix + mesh_edges_schemas_dict["color"]["rpc"]) - def setMeshEdgesColor(self, params): + def setMeshEdgesColor(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.mesh_edges_schemas_dict["color"], self.mesh_edges_prefix + rpc_params, self.mesh_edges_schemas_dict["color"], self.mesh_edges_prefix ) - id, red, green, blue = ( - params["id"], - params["color"]["r"], - params["color"]["g"], - params["color"]["b"], - ) - self.SetEdgesColor(id, red, green, blue) + params = schemas.Color.from_dict(rpc_params) + color = params.color + self.SetEdgesColor(params.id, color.r, color.g, color.b) @exportRpc(mesh_edges_prefix + mesh_edges_schemas_dict["width"]["rpc"]) - def setMeshEdgesWidth(self, params): + def setMeshEdgesWidth(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.mesh_edges_schemas_dict["width"], self.mesh_edges_prefix + rpc_params, self.mesh_edges_schemas_dict["width"], self.mesh_edges_prefix ) - id, size = params["id"], params["width"] - self.SetEdgesWidth(id, width) + params = schemas.Width.from_dict(rpc_params) + self.SetEdgesWidth(params.id, params.width) diff --git a/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/__init__.py new file mode 100644 index 0000000..27cf1d7 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/__init__.py @@ -0,0 +1,5 @@ +from .width import * +from .visibility import * +from .vertex_attribute import * +from .size import * +from .color import * diff --git a/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/color.py b/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/color.py new file mode 100644 index 0000000..87f4735 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/color.py @@ -0,0 +1,17 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional + + +@dataclass +class ColorClass(DataClassJsonMixin): + b: int + g: int + r: int + a: Optional[float] = None + + +@dataclass +class Color(DataClassJsonMixin): + color: ColorClass + id: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/size.py b/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/size.py new file mode 100644 index 0000000..d10819a --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/size.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Size(DataClassJsonMixin): + id: str + size: int diff --git a/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/vertex_attribute.py b/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/vertex_attribute.py new file mode 100644 index 0000000..b6b7766 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/vertex_attribute.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class VertexAttribute(DataClassJsonMixin): + id: str + name: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/visibility.py b/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/visibility.py new file mode 100644 index 0000000..78c2b5c --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/visibility.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Visibility(DataClassJsonMixin): + id: str + visibility: bool diff --git a/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/width.py b/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/width.py new file mode 100644 index 0000000..f51023a --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/edges/schemas/width.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Width(DataClassJsonMixin): + id: str + width: float diff --git a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py index 52f292f..c5e3b9a 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/mesh_protocols.py @@ -1,20 +1,23 @@ # Standard library imports import os -from typing import cast # Third party imports -import vtk -from wslink import register as exportRpc +from wslink import register as exportRpc # type: ignore +from vtkmodules.vtkIOXML import vtkXMLGenericDataObjectReader, vtkXMLImageDataReader +from vtkmodules.vtkRenderingCore import vtkDataSetMapper, vtkActor, vtkTexture +from vtkmodules.vtkCommonDataModel import vtkDataSet, vtkCellTypes +from vtkmodules.vtkCommonExecutionModel import vtkAlgorithm from opengeodeweb_microservice.database.data import Data +from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports from opengeodeweb_viewer.utils_functions import ( - get_schemas_dict, validate_schema, RpcParams, - RpcParamsWithColor, ) from opengeodeweb_viewer.object.object_methods import VtkObjectView +from opengeodeweb_viewer.vtk_protocol import vtkData +from . import schemas class VtkMeshView(VtkObjectView): @@ -27,24 +30,23 @@ def __init__(self) -> None: super().__init__() @exportRpc(mesh_prefix + mesh_schemas_dict["register"]["rpc"]) - def registerMesh(self, params: RpcParams) -> None: + def registerMesh(self, rpc_params: RpcParams) -> None: print(f"{self.mesh_schemas_dict["register"]}", flush=True) - validate_schema(params, self.mesh_schemas_dict["register"], self.mesh_prefix) - data_id = str(params["id"]) + validate_schema( + rpc_params, self.mesh_schemas_dict["register"], self.mesh_prefix + ) + params = schemas.Register.from_dict(rpc_params) + data_id = params.id try: - data = self.get_data(data_id) - file_name = str(data["viewable_file_name"]) - - reader = vtk.vtkXMLGenericDataObjectReader() - filter = {} - mapper = vtk.vtkDataSetMapper() + file_name = str(self.get_data(data_id)["viewable_file_name"]) + reader = vtkXMLGenericDataObjectReader() + mapper = vtkDataSetMapper() mapper.SetInputConnection(reader.GetOutputPort()) - - self.registerObject(data_id, file_name, reader, filter, mapper) - + data = vtkData(reader, mapper) + self.registerObject(data_id, file_name, data) data_object = reader.GetOutput() - data_set = vtk.vtkDataSet.SafeDownCast(data_object) - cell_types = vtk.vtkCellTypes() + data_set = vtkDataSet.SafeDownCast(data_object) + cell_types = vtkCellTypes() data_set.GetCellTypes(cell_types) cell_data = cell_types.GetCellTypesArray() max_id = -1 @@ -52,106 +54,97 @@ def registerMesh(self, params: RpcParams) -> None: t_id = cell_data.GetValue(t) max_id = max(max_id, t_id) print(f"{max_id=}", flush=True) - max_dimension = "" if max_id < 3: - max_dimension = "points" + data.max_dimension = "points" elif max_id < 5: - max_dimension = "edges" + data.max_dimension = "edges" elif max_id < 7: - max_dimension = "polygons" + data.max_dimension = "polygons" elif max_id >= 7: - max_dimension = "polyhedra" - self.get_data_base()[data_id]["max_dimension"] = max_dimension + data.max_dimension = "polyhedra" except Exception as e: print(f"Error registering mesh {data_id}: {str(e)}", flush=True) raise @exportRpc(mesh_prefix + mesh_schemas_dict["deregister"]["rpc"]) - def deregisterMesh(self, params: RpcParams) -> None: - validate_schema(params, self.mesh_schemas_dict["deregister"], self.mesh_prefix) - data_id = str(params["id"]) - self.deregisterObject(data_id) + def deregisterMesh(self, rpc_params: RpcParams) -> None: + validate_schema( + rpc_params, self.mesh_schemas_dict["deregister"], self.mesh_prefix + ) + params = schemas.Deregister.from_dict(rpc_params) + self.deregisterObject(params.id) @exportRpc(mesh_prefix + mesh_schemas_dict["visibility"]["rpc"]) - def SetMeshVisibility(self, params: RpcParams) -> None: - validate_schema(params, self.mesh_schemas_dict["visibility"], self.mesh_prefix) - data_id, visibility = str(params["id"]), bool(params["visibility"]) - self.SetVisibility(data_id, visibility) + def SetMeshVisibility(self, rpc_params: RpcParams) -> None: + validate_schema( + rpc_params, self.mesh_schemas_dict["visibility"], self.mesh_prefix + ) + params = schemas.Visibility.from_dict(rpc_params) + self.SetVisibility(params.id, params.visibility) @exportRpc(mesh_prefix + mesh_schemas_dict["opacity"]["rpc"]) - def setMeshOpacity(self, params: RpcParams) -> None: - validate_schema(params, self.mesh_schemas_dict["opacity"], self.mesh_prefix) - data_id, opacity = str(params["id"]), float( - cast(int | float, params["opacity"]) - ) - self.SetOpacity(data_id, opacity) + def setMeshOpacity(self, rpc_params: RpcParams) -> None: + validate_schema(rpc_params, self.mesh_schemas_dict["opacity"], self.mesh_prefix) + params = schemas.Opacity.from_dict(rpc_params) + self.SetOpacity(params.id, params.opacity) @exportRpc(mesh_prefix + mesh_schemas_dict["color"]["rpc"]) - def setMeshColor(self, params: RpcParamsWithColor) -> None: - validate_schema(params, self.mesh_schemas_dict["color"], self.mesh_prefix) - color_dict = cast(dict[str, int], params["color"]) - data_id, red, green, blue = ( - str(params["id"]), - int(color_dict["r"]), - int(color_dict["g"]), - int(color_dict["b"]), - ) - self.SetColor(data_id, red, green, blue) + def setMeshColor(self, rpc_params: RpcParams) -> None: + validate_schema(rpc_params, self.mesh_schemas_dict["color"], self.mesh_prefix) + params = schemas.Color.from_dict(rpc_params) + color = params.color + self.SetColor(params.id, color.r, color.g, color.b) @exportRpc(mesh_prefix + mesh_schemas_dict["apply_textures"]["rpc"]) - def meshApplyTextures(self, params: RpcParams) -> None: + def meshApplyTextures(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.mesh_schemas_dict["apply_textures"], self.mesh_prefix + rpc_params, self.mesh_schemas_dict["apply_textures"], self.mesh_prefix ) - data_id = str(params["id"]) - textures_info = cast(list[dict[str, str]], params["textures"]) - self.applyTextures(data_id, textures_info) - - def applyTextures(self, mesh_id: str, textures_info: list[dict[str, str]]) -> None: - for tex_info in textures_info: - texture_id = tex_info["id"] - texture_name = tex_info["texture_name"] + params = schemas.ApplyTextures.from_dict(rpc_params) + mesh_id = params.id + for tex_info in params.textures: + texture_id = tex_info.id texture_data = Data.get(texture_id) - if not texture_data: + if texture_data is None: continue - texture_file = str(texture_data.viewable_file_name) + texture_file = texture_data.viewable_file_name if not texture_file.lower().endswith(".vti"): continue texture_file_path = self.get_data_file_path(texture_id) - texture_reader = vtk.vtkXMLImageDataReader() + texture_reader = vtkXMLImageDataReader() texture_reader.SetFileName(texture_file_path) texture_reader.Update() - texture = vtk.vtkTexture() + texture = vtkTexture() texture.SetInputConnection(texture_reader.GetOutputPort()) texture.InterpolateOn() - reader = cast(vtk.vtkAlgorithm, self.get_object(mesh_id)["reader"]) + reader = self.get_object(mesh_id).reader output = reader.GetOutput() point_data = output.GetPointData() for i in range(point_data.GetNumberOfArrays()): array = point_data.GetArray(i) - if array.GetName() == texture_name: + if array.GetName() == tex_info.texture_name: point_data.SetTCoords(array) break - actor = cast(vtk.vtkActor, self.get_object(mesh_id)["actor"]) + actor = self.get_object(mesh_id).actor actor.SetTexture(texture) self.render() def displayAttributeOnVertices(self, data_id: str, name: str) -> None: - reader = self.get_object(data_id)["reader"] + reader = self.get_object(data_id).reader points = reader.GetOutput().GetPointData() points.SetActiveScalars(name) - mapper = self.get_object(data_id)["mapper"] + mapper = self.get_object(data_id).mapper mapper.ScalarVisibilityOn() mapper.SetScalarModeToUsePointData() mapper.SetScalarRange(points.GetScalars().GetRange()) self.render() def displayAttributeOnCells(self, data_id: str, name: str) -> None: - reader = self.get_object(data_id)["reader"] + reader = self.get_object(data_id).reader cells = reader.GetOutput().GetCellData() cells.SetActiveScalars(name) - mapper = self.get_object(data_id)["mapper"] + mapper = self.get_object(data_id).mapper mapper.ScalarVisibilityOn() mapper.SetScalarModeToUseCellData() mapper.SetScalarRange(cells.GetScalars().GetRange()) diff --git a/src/opengeodeweb_viewer/rpc/mesh/points/mesh_points_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/points/mesh_points_protocols.py index 613a96c..1c79b3f 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/points/mesh_points_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/points/mesh_points_protocols.py @@ -3,15 +3,15 @@ # Third party imports from wslink import register as exportRpc +from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports from opengeodeweb_viewer.utils_functions import ( - get_schemas_dict, validate_schema, RpcParams, - RpcParamsWithColor, ) from opengeodeweb_viewer.rpc.mesh.mesh_protocols import VtkMeshView +from . import schemas class VtkMeshPointsView(VtkMeshView): @@ -24,40 +24,38 @@ def __init__(self) -> None: super().__init__() @exportRpc(mesh_points_prefix + mesh_points_schemas_dict["visibility"]["rpc"]) - def setMeshPointsVisibility(self, params: RpcParams) -> None: + def setMeshPointsVisibility(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.mesh_points_schemas_dict["visibility"], self.mesh_points_prefix + rpc_params, + self.mesh_points_schemas_dict["visibility"], + self.mesh_points_prefix, ) - id, visibility = params["id"], params["visibility"] - self.SetPointsVisibility(id, visibility) + params = schemas.Visibility.from_dict(rpc_params) + self.SetPointsVisibility(params.id, params.visibility) @exportRpc(mesh_points_prefix + mesh_points_schemas_dict["color"]["rpc"]) - def setMeshPointsColor(self, params: RpcParamsWithColor) -> None: + def setMeshPointsColor(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.mesh_points_schemas_dict["color"], self.mesh_points_prefix - ) - id, red, green, blue = ( - params["id"], - params["color"]["r"], - params["color"]["g"], - params["color"]["b"], + rpc_params, self.mesh_points_schemas_dict["color"], self.mesh_points_prefix ) - self.SetPointsColor(id, red, green, blue) + params = schemas.Color.from_dict(rpc_params) + color = params.color + self.SetPointsColor(params.id, color.r, color.g, color.b) @exportRpc(mesh_points_prefix + mesh_points_schemas_dict["size"]["rpc"]) - def setMeshPointsSize(self, params: RpcParams) -> None: + def setMeshPointsSize(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.mesh_points_schemas_dict["size"], self.mesh_points_prefix + rpc_params, self.mesh_points_schemas_dict["size"], self.mesh_points_prefix ) - id, size = params["id"], params["size"] - self.SetPointsSize(id, size) + params = schemas.Size.from_dict(rpc_params) + self.SetPointsSize(params.id, params.size) @exportRpc(mesh_points_prefix + mesh_points_schemas_dict["vertex_attribute"]["rpc"]) - def setMeshPointsVertexAttribute(self, params: RpcParams) -> None: + def setMeshPointsVertexAttribute(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.mesh_points_schemas_dict["vertex_attribute"], self.mesh_points_prefix, ) - id, name = params["id"], params["name"] - self.displayAttributeOnVertices(id, name) + params = schemas.VertexAttribute.from_dict(rpc_params) + self.displayAttributeOnVertices(params.id, params.name) diff --git a/src/opengeodeweb_viewer/rpc/mesh/points/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/mesh/points/schemas/__init__.py new file mode 100644 index 0000000..67bb8fc --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/points/schemas/__init__.py @@ -0,0 +1,4 @@ +from .visibility import * +from .vertex_attribute import * +from .size import * +from .color import * diff --git a/src/opengeodeweb_viewer/rpc/mesh/points/schemas/color.py b/src/opengeodeweb_viewer/rpc/mesh/points/schemas/color.py new file mode 100644 index 0000000..87f4735 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/points/schemas/color.py @@ -0,0 +1,17 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional + + +@dataclass +class ColorClass(DataClassJsonMixin): + b: int + g: int + r: int + a: Optional[float] = None + + +@dataclass +class Color(DataClassJsonMixin): + color: ColorClass + id: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/points/schemas/size.py b/src/opengeodeweb_viewer/rpc/mesh/points/schemas/size.py new file mode 100644 index 0000000..3ed13eb --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/points/schemas/size.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Size(DataClassJsonMixin): + id: str + size: float diff --git a/src/opengeodeweb_viewer/rpc/mesh/points/schemas/vertex_attribute.py b/src/opengeodeweb_viewer/rpc/mesh/points/schemas/vertex_attribute.py new file mode 100644 index 0000000..b6b7766 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/points/schemas/vertex_attribute.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class VertexAttribute(DataClassJsonMixin): + id: str + name: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/points/schemas/visibility.py b/src/opengeodeweb_viewer/rpc/mesh/points/schemas/visibility.py new file mode 100644 index 0000000..78c2b5c --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/points/schemas/visibility.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Visibility(DataClassJsonMixin): + id: str + visibility: bool diff --git a/src/opengeodeweb_viewer/rpc/mesh/polygons/polygons_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/polygons/polygons_protocols.py index dbb0970..8ca9eec 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/polygons/polygons_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/polygons/polygons_protocols.py @@ -2,11 +2,16 @@ import os # Third party imports -from wslink import register as exportRpc +from wslink import register as exportRpc # type: ignore +from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports -from opengeodeweb_viewer.utils_functions import get_schemas_dict, validate_schema +from opengeodeweb_viewer.utils_functions import ( + validate_schema, + RpcParams, +) from opengeodeweb_viewer.rpc.mesh.mesh_protocols import VtkMeshView +from . import schemas class VtkMeshPolygonsView(VtkMeshView): @@ -19,50 +24,46 @@ def __init__(self): super().__init__() @exportRpc(mesh_polygons_prefix + mesh_polygons_schemas_dict["visibility"]["rpc"]) - def setMeshPolygonsVisibility(self, params): + def setMeshPolygonsVisibility(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.mesh_polygons_schemas_dict["visibility"], self.mesh_polygons_prefix, ) - id, visibility = params["id"], params["visibility"] - self.SetVisibility(id, visibility) + params = schemas.Visibility.from_dict(rpc_params) + self.SetVisibility(params.id, params.visibility) @exportRpc(mesh_polygons_prefix + mesh_polygons_schemas_dict["color"]["rpc"]) - def setMeshPolygonsColor(self, params): + def setMeshPolygonsColor(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.mesh_polygons_schemas_dict["color"], self.mesh_polygons_prefix, ) - id, red, green, blue = ( - params["id"], - params["color"]["r"], - params["color"]["g"], - params["color"]["b"], - ) - self.SetColor(id, red, green, blue) + params = schemas.Color.from_dict(rpc_params) + color = params.color + self.SetColor(params.id, color.r, color.g, color.b) @exportRpc( mesh_polygons_prefix + mesh_polygons_schemas_dict["vertex_attribute"]["rpc"] ) - def setMeshPolygonsVertexAttribute(self, params): + def setMeshPolygonsVertexAttribute(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.mesh_polygons_schemas_dict["vertex_attribute"], self.mesh_polygons_prefix, ) - id, name = params["id"], params["name"] - self.displayAttributeOnVertices(id, name) + params = schemas.VertexAttribute.from_dict(rpc_params) + self.displayAttributeOnVertices(params.id, params.name) @exportRpc( mesh_polygons_prefix + mesh_polygons_schemas_dict["polygon_attribute"]["rpc"] ) - def setMeshPolygonsPolygonAttribute(self, params): + def setMeshPolygonsPolygonAttribute(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.mesh_polygons_schemas_dict["polygon_attribute"], self.mesh_polygons_prefix, ) - id, name = params["id"], params["name"] - self.displayAttributeOnCells(id, name) + params = schemas.PolygonAttribute.from_dict(rpc_params) + self.displayAttributeOnCells(params.id, params.name) diff --git a/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/__init__.py new file mode 100644 index 0000000..4085e8c --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/__init__.py @@ -0,0 +1,4 @@ +from .visibility import * +from .vertex_attribute import * +from .polygon_attribute import * +from .color import * diff --git a/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/color.py b/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/color.py new file mode 100644 index 0000000..87f4735 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/color.py @@ -0,0 +1,17 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional + + +@dataclass +class ColorClass(DataClassJsonMixin): + b: int + g: int + r: int + a: Optional[float] = None + + +@dataclass +class Color(DataClassJsonMixin): + color: ColorClass + id: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/polygon_attribute.py b/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/polygon_attribute.py new file mode 100644 index 0000000..64a1b1a --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/polygon_attribute.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class PolygonAttribute(DataClassJsonMixin): + id: str + name: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/vertex_attribute.py b/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/vertex_attribute.py new file mode 100644 index 0000000..b6b7766 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/vertex_attribute.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class VertexAttribute(DataClassJsonMixin): + id: str + name: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/visibility.py b/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/visibility.py new file mode 100644 index 0000000..78c2b5c --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/polygons/schemas/visibility.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Visibility(DataClassJsonMixin): + id: str + visibility: bool diff --git a/src/opengeodeweb_viewer/rpc/mesh/polyhedra/polyhedra_protocols.py b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/polyhedra_protocols.py index a805d99..4931b35 100644 --- a/src/opengeodeweb_viewer/rpc/mesh/polyhedra/polyhedra_protocols.py +++ b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/polyhedra_protocols.py @@ -2,11 +2,16 @@ import os # Third party imports -from wslink import register as exportRpc +from wslink import register as exportRpc # type: ignore +from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports -from opengeodeweb_viewer.utils_functions import get_schemas_dict, validate_schema +from opengeodeweb_viewer.utils_functions import ( + validate_schema, + RpcParams, +) from opengeodeweb_viewer.rpc.mesh.mesh_protocols import VtkMeshView +from . import schemas class VtkMeshPolyhedraView(VtkMeshView): @@ -19,51 +24,47 @@ def __init__(self): super().__init__() @exportRpc(mesh_polyhedra_prefix + mesh_polyhedra_schemas_dict["visibility"]["rpc"]) - def setMeshPolyhedraVisibility(self, params): + def setMeshPolyhedraVisibility(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.mesh_polyhedra_schemas_dict["visibility"], self.mesh_polyhedra_prefix, ) - id, visibility = params["id"], params["visibility"] - self.SetVisibility(id, visibility) + params = schemas.Visibility.from_dict(rpc_params) + self.SetVisibility(params.id, params.visibility) @exportRpc(mesh_polyhedra_prefix + mesh_polyhedra_schemas_dict["color"]["rpc"]) - def setMeshPolyhedraColor(self, params): + def setMeshPolyhedraColor(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.mesh_polyhedra_schemas_dict["color"], self.mesh_polyhedra_prefix, ) - id, red, green, blue = ( - params["id"], - params["color"]["r"], - params["color"]["g"], - params["color"]["b"], - ) - self.SetColor(id, red, green, blue) + params = schemas.Color.from_dict(rpc_params) + color = params.color + self.SetColor(params.id, color.r, color.g, color.b) @exportRpc( mesh_polyhedra_prefix + mesh_polyhedra_schemas_dict["vertex_attribute"]["rpc"] ) - def setMeshPolyhedraVertexAttribute(self, params): + def setMeshPolyhedraVertexAttribute(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.mesh_polyhedra_schemas_dict["vertex_attribute"], self.mesh_polyhedra_prefix, ) - id, name = params["id"], params["name"] - self.displayAttributeOnVertices(id, name) + params = schemas.VertexAttribute.from_dict(rpc_params) + self.displayAttributeOnVertices(params.id, params.name) @exportRpc( mesh_polyhedra_prefix + mesh_polyhedra_schemas_dict["polyhedron_attribute"]["rpc"] ) - def setMeshPolyhedraPolyhedronAttribute(self, params): + def setMeshPolyhedraPolyhedronAttribute(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.mesh_polyhedra_schemas_dict["polyhedron_attribute"], self.mesh_polyhedra_prefix, ) - id, name = params["id"], params["name"] - self.displayAttributeOnCells(id, name) + params = schemas.PolyhedronAttribute.from_dict(rpc_params) + self.displayAttributeOnCells(params.id, params.name) diff --git a/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/__init__.py new file mode 100644 index 0000000..40aad4f --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/__init__.py @@ -0,0 +1,4 @@ +from .visibility import * +from .vertex_attribute import * +from .polyhedron_attribute import * +from .color import * diff --git a/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/color.py b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/color.py new file mode 100644 index 0000000..87f4735 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/color.py @@ -0,0 +1,17 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional + + +@dataclass +class ColorClass(DataClassJsonMixin): + b: int + g: int + r: int + a: Optional[float] = None + + +@dataclass +class Color(DataClassJsonMixin): + color: ColorClass + id: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/polyhedron_attribute.py b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/polyhedron_attribute.py new file mode 100644 index 0000000..465685e --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/polyhedron_attribute.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class PolyhedronAttribute(DataClassJsonMixin): + id: str + name: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/vertex_attribute.py b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/vertex_attribute.py new file mode 100644 index 0000000..b6b7766 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/vertex_attribute.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class VertexAttribute(DataClassJsonMixin): + id: str + name: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/visibility.py b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/visibility.py new file mode 100644 index 0000000..78c2b5c --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/polyhedra/schemas/visibility.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Visibility(DataClassJsonMixin): + id: str + visibility: bool diff --git a/src/opengeodeweb_viewer/rpc/mesh/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/mesh/schemas/__init__.py new file mode 100644 index 0000000..e6b398e --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/schemas/__init__.py @@ -0,0 +1,6 @@ +from .visibility import * +from .register import * +from .opacity import * +from .deregister import * +from .color import * +from .apply_textures import * diff --git a/src/opengeodeweb_viewer/rpc/mesh/schemas/apply_textures.py b/src/opengeodeweb_viewer/rpc/mesh/schemas/apply_textures.py new file mode 100644 index 0000000..1a10c08 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/schemas/apply_textures.py @@ -0,0 +1,15 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import List + + +@dataclass +class Texture(DataClassJsonMixin): + id: str + texture_name: str + + +@dataclass +class ApplyTextures(DataClassJsonMixin): + id: str + textures: List[Texture] diff --git a/src/opengeodeweb_viewer/rpc/mesh/schemas/color.py b/src/opengeodeweb_viewer/rpc/mesh/schemas/color.py new file mode 100644 index 0000000..a1e2a3f --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/schemas/color.py @@ -0,0 +1,15 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class ColorClass(DataClassJsonMixin): + b: int + g: int + r: int + + +@dataclass +class Color(DataClassJsonMixin): + color: ColorClass + id: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/schemas/deregister.py b/src/opengeodeweb_viewer/rpc/mesh/schemas/deregister.py new file mode 100644 index 0000000..f9c0aee --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/schemas/deregister.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Deregister(DataClassJsonMixin): + id: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/schemas/opacity.py b/src/opengeodeweb_viewer/rpc/mesh/schemas/opacity.py new file mode 100644 index 0000000..a6215df --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/schemas/opacity.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Opacity(DataClassJsonMixin): + id: str + opacity: float diff --git a/src/opengeodeweb_viewer/rpc/mesh/schemas/register.py b/src/opengeodeweb_viewer/rpc/mesh/schemas/register.py new file mode 100644 index 0000000..e15e699 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/schemas/register.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Register(DataClassJsonMixin): + id: str diff --git a/src/opengeodeweb_viewer/rpc/mesh/schemas/visibility.py b/src/opengeodeweb_viewer/rpc/mesh/schemas/visibility.py new file mode 100644 index 0000000..78c2b5c --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/mesh/schemas/visibility.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Visibility(DataClassJsonMixin): + id: str + visibility: bool 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 eee2811..6db1208 100644 --- a/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/blocks/model_blocks_protocols.py @@ -2,11 +2,16 @@ import os # Third party imports -from wslink import register as exportRpc +from wslink import register as exportRpc # type: ignore +from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports -from opengeodeweb_viewer.utils_functions import get_schemas_dict, validate_schema +from opengeodeweb_viewer.utils_functions import ( + validate_schema, + RpcParams, +) from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView +from . import schemas class VtkModelBlocksView(VtkModelView): @@ -19,31 +24,22 @@ def __init__(self): super().__init__() @exportRpc(model_blocks_prefix + model_blocks_schemas_dict["visibility"]["rpc"]) - def setModelBlocksPolyhedraVisibility(self, params): + def setModelBlocksPolyhedraVisibility(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.model_blocks_schemas_dict["visibility"], self.model_blocks_prefix, ) - id, block_ids, visibility = ( - params["id"], - params["block_ids"], - params["visibility"], - ) - self.SetBlocksVisibility(id, block_ids, visibility) + params = schemas.Visibility.from_dict(rpc_params) + self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_blocks_prefix + model_blocks_schemas_dict["color"]["rpc"]) - def setModelBlocksPolyhedraColor(self, params): + def setModelBlocksPolyhedraColor(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.model_blocks_schemas_dict["color"], self.model_blocks_prefix, ) - id, block_ids, red, green, blue = ( - params["id"], - params["block_ids"], - params["color"]["r"], - params["color"]["g"], - params["color"]["b"], - ) - self.SetBlocksColor(id, block_ids, red, green, blue) + params = schemas.Color.from_dict(rpc_params) + color = params.color + self.SetBlocksColor(params.id, params.block_ids, color.r, color.g, color.b) diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/__init__.py new file mode 100644 index 0000000..e983533 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/__init__.py @@ -0,0 +1,2 @@ +from .visibility import * +from .color import * diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py new file mode 100644 index 0000000..3c52ca4 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/color.py @@ -0,0 +1,18 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List + + +@dataclass +class ColorClass(DataClassJsonMixin): + b: int + g: int + r: int + a: Optional[float] = None + + +@dataclass +class Color(DataClassJsonMixin): + block_ids: List[int] + color: ColorClass + id: str diff --git a/src/opengeodeweb_viewer/rpc/model/blocks/schemas/visibility.py b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/visibility.py new file mode 100644 index 0000000..0e79ba2 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/blocks/schemas/visibility.py @@ -0,0 +1,10 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import List + + +@dataclass +class Visibility(DataClassJsonMixin): + block_ids: List[int] + id: str + visibility: bool 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 3e0df02..3e6a3ee 100644 --- a/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/corners/model_corners_protocols.py @@ -2,11 +2,16 @@ import os # Third party imports -from wslink import register as exportRpc +from wslink import register as exportRpc # type: ignore +from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports -from opengeodeweb_viewer.utils_functions import get_schemas_dict, validate_schema +from opengeodeweb_viewer.utils_functions import ( + validate_schema, + RpcParams, +) from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView +from . import schemas class VtkModelCornersView(VtkModelView): @@ -19,31 +24,22 @@ def __init__(self): super().__init__() @exportRpc(model_corners_prefix + model_corners_schemas_dict["visibility"]["rpc"]) - def setModelCornersPointsVisibility(self, params): + def setModelCornersPointsVisibility(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.model_corners_schemas_dict["visibility"], self.model_corners_prefix, ) - id, block_ids, visibility = ( - params["id"], - params["block_ids"], - params["visibility"], - ) - self.SetBlocksVisibility(id, block_ids, visibility) + params = schemas.Visibility.from_dict(rpc_params) + self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_corners_prefix + model_corners_schemas_dict["color"]["rpc"]) - def setModelCornersPointsColor(self, params): + def setModelCornersPointsColor(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.model_corners_schemas_dict["color"], self.model_corners_prefix, ) - id, block_ids, red, green, blue = ( - params["id"], - params["block_ids"], - params["color"]["r"], - params["color"]["g"], - params["color"]["b"], - ) - self.SetBlocksColor(id, block_ids, red, green, blue) + params = schemas.Color.from_dict(rpc_params) + color = params.color + self.SetBlocksColor(params.id, params.block_ids, color.r, color.g, color.b) diff --git a/src/opengeodeweb_viewer/rpc/model/corners/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/model/corners/schemas/__init__.py new file mode 100644 index 0000000..e983533 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/corners/schemas/__init__.py @@ -0,0 +1,2 @@ +from .visibility import * +from .color import * diff --git a/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py new file mode 100644 index 0000000..3c52ca4 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/corners/schemas/color.py @@ -0,0 +1,18 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List + + +@dataclass +class ColorClass(DataClassJsonMixin): + b: int + g: int + r: int + a: Optional[float] = None + + +@dataclass +class Color(DataClassJsonMixin): + block_ids: List[int] + color: ColorClass + id: str diff --git a/src/opengeodeweb_viewer/rpc/model/corners/schemas/visibility.py b/src/opengeodeweb_viewer/rpc/model/corners/schemas/visibility.py new file mode 100644 index 0000000..0e79ba2 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/corners/schemas/visibility.py @@ -0,0 +1,10 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import List + + +@dataclass +class Visibility(DataClassJsonMixin): + block_ids: List[int] + id: str + visibility: bool diff --git a/src/opengeodeweb_viewer/rpc/model/edges/model_edges_protocols.py b/src/opengeodeweb_viewer/rpc/model/edges/model_edges_protocols.py index 8aace53..2ed35a3 100644 --- a/src/opengeodeweb_viewer/rpc/model/edges/model_edges_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/edges/model_edges_protocols.py @@ -2,11 +2,16 @@ import os # Third party imports -from wslink import register as exportRpc +from wslink import register as exportRpc # type: ignore +from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports -from opengeodeweb_viewer.utils_functions import get_schemas_dict, validate_schema +from opengeodeweb_viewer.utils_functions import ( + validate_schema, + RpcParams, +) from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView +from . import schemas class VtkModelEdgesView(VtkModelView): @@ -19,9 +24,11 @@ def __init__(self): super().__init__() @exportRpc(model_edges_prefix + model_edges_schemas_dict["visibility"]["rpc"]) - def setModelEdgesVisibility(self, params): + def setModelEdgesVisibility(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.model_edges_schemas_dict["visibility"], self.model_edges_prefix + rpc_params, + self.model_edges_schemas_dict["visibility"], + self.model_edges_prefix, ) - id, visibility = params["id"], params["visibility"] - self.SetEdgesVisibility(id, visibility) + params = schemas.Visibility.from_dict(rpc_params) + self.SetEdgesVisibility(params.id, params.visibility) diff --git a/src/opengeodeweb_viewer/rpc/model/edges/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/model/edges/schemas/__init__.py new file mode 100644 index 0000000..cbc73c0 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/edges/schemas/__init__.py @@ -0,0 +1 @@ +from .visibility import * diff --git a/src/opengeodeweb_viewer/rpc/model/edges/schemas/visibility.py b/src/opengeodeweb_viewer/rpc/model/edges/schemas/visibility.py new file mode 100644 index 0000000..78c2b5c --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/edges/schemas/visibility.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Visibility(DataClassJsonMixin): + id: str + visibility: bool 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 afec4e6..76e18d4 100644 --- a/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/lines/model_lines_protocols.py @@ -2,11 +2,16 @@ import os # Third party imports -from wslink import register as exportRpc +from wslink import register as exportRpc # type: ignore +from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports -from opengeodeweb_viewer.utils_functions import get_schemas_dict, validate_schema +from opengeodeweb_viewer.utils_functions import ( + validate_schema, + RpcParams, +) from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView +from . import schemas class VtkModelLinesView(VtkModelView): @@ -19,31 +24,22 @@ def __init__(self): super().__init__() @exportRpc(model_lines_prefix + model_lines_schemas_dict["visibility"]["rpc"]) - def setModelLinesEdgesVisibility(self, params): + def setModelLinesEdgesVisibility(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.model_lines_schemas_dict["visibility"], self.model_lines_prefix, ) - id, block_ids, visibility = ( - params["id"], - params["block_ids"], - params["visibility"], - ) - self.SetBlocksVisibility(id, block_ids, visibility) + params = schemas.Visibility.from_dict(rpc_params) + self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_lines_prefix + model_lines_schemas_dict["color"]["rpc"]) - def setModelLinesEdgesColor(self, params): + def setModelLinesEdgesColor(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.model_lines_schemas_dict["color"], self.model_lines_prefix, ) - id, block_ids, red, green, blue = ( - params["id"], - params["block_ids"], - params["color"]["r"], - params["color"]["g"], - params["color"]["b"], - ) - self.SetBlocksColor(id, block_ids, red, green, blue) + params = schemas.Color.from_dict(rpc_params) + color = params.color + self.SetBlocksColor(params.id, params.block_ids, color.r, color.g, color.b) diff --git a/src/opengeodeweb_viewer/rpc/model/lines/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/model/lines/schemas/__init__.py new file mode 100644 index 0000000..e983533 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/lines/schemas/__init__.py @@ -0,0 +1,2 @@ +from .visibility import * +from .color import * diff --git a/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py new file mode 100644 index 0000000..3c52ca4 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/lines/schemas/color.py @@ -0,0 +1,18 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List + + +@dataclass +class ColorClass(DataClassJsonMixin): + b: int + g: int + r: int + a: Optional[float] = None + + +@dataclass +class Color(DataClassJsonMixin): + block_ids: List[int] + color: ColorClass + id: str diff --git a/src/opengeodeweb_viewer/rpc/model/lines/schemas/visibility.py b/src/opengeodeweb_viewer/rpc/model/lines/schemas/visibility.py new file mode 100644 index 0000000..0e79ba2 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/lines/schemas/visibility.py @@ -0,0 +1,10 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import List + + +@dataclass +class Visibility(DataClassJsonMixin): + block_ids: List[int] + id: str + visibility: bool diff --git a/src/opengeodeweb_viewer/rpc/model/model_protocols.py b/src/opengeodeweb_viewer/rpc/model/model_protocols.py index a4ada87..c57df76 100644 --- a/src/opengeodeweb_viewer/rpc/model/model_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/model_protocols.py @@ -2,13 +2,23 @@ import os # Third party imports -import vtk -from vtkmodules.vtkRenderingCore import vtkCompositeDataDisplayAttributes -from wslink import register as exportRpc +from vtkmodules.vtkRenderingCore import ( + vtkCompositeDataDisplayAttributes, + vtkCompositePolyDataMapper, +) +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.utils_functions import get_schemas_dict, validate_schema +from opengeodeweb_viewer.utils_functions import ( + validate_schema, + RpcParams, +) from opengeodeweb_viewer.object.object_methods import VtkObjectView +from opengeodeweb_viewer.vtk_protocol import vtkData +from . import schemas class VtkModelView(VtkObjectView): @@ -21,38 +31,39 @@ def __init__(self): super().__init__() @exportRpc(model_prefix + model_schemas_dict["register"]["rpc"]) - def registerModel(self, params): - validate_schema(params, self.model_schemas_dict["register"], self.model_prefix) - data_id = params["id"] + def registerModel(self, rpc_params: RpcParams) -> None: + validate_schema( + rpc_params, self.model_schemas_dict["register"], self.model_prefix + ) + params = schemas.Register.from_dict(rpc_params) + data_id = params.id try: - data = self.get_data(data_id) - file_name = str(data["viewable_file_name"]) - - reader = vtk.vtkXMLMultiBlockDataReader() - filter = vtk.vtkGeometryFilter() + file_name = str(self.get_data(data_id)["viewable_file_name"]) + reader = vtkXMLMultiBlockDataReader() + filter = vtkGeometryFilter() filter.SetInputConnection(reader.GetOutputPort()) - mapper = vtk.vtkCompositePolyDataMapper() + mapper = vtkCompositePolyDataMapper() mapper.SetInputConnection(filter.GetOutputPort()) attributes = vtkCompositeDataDisplayAttributes() mapper.SetCompositeDataDisplayAttributes(attributes) - self.registerObject(data_id, file_name, reader, filter, mapper) - self.get_object(data_id)["max_dimension"] = "default" + data = vtkData(reader, mapper, filter) + self.registerObject(data_id, file_name, data) except Exception as e: print(f"Error registering model {data_id}: {str(e)}", flush=True) raise @exportRpc(model_prefix + model_schemas_dict["deregister"]["rpc"]) - def deregisterModel(self, params): + def deregisterModel(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.model_schemas_dict["deregister"], self.model_prefix + rpc_params, self.model_schemas_dict["deregister"], self.model_prefix ) - data_id = params["id"] - self.deregisterObject(data_id) + params = schemas.Deregister.from_dict(rpc_params) + self.deregisterObject(params.id) @exportRpc(model_prefix + model_schemas_dict["visibility"]["rpc"]) - def setModelVisibility(self, params): + def setModelVisibility(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.model_schemas_dict["visibility"], self.model_prefix + rpc_params, self.model_schemas_dict["visibility"], self.model_prefix ) - data_id, visibility = params["id"], params["visibility"] - self.SetVisibility(data_id, visibility) + params = schemas.Visibility.from_dict(rpc_params) + self.SetVisibility(params.id, params.visibility) diff --git a/src/opengeodeweb_viewer/rpc/model/points/model_points_protocols.py b/src/opengeodeweb_viewer/rpc/model/points/model_points_protocols.py index 77a8015..5a71046 100644 --- a/src/opengeodeweb_viewer/rpc/model/points/model_points_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/points/model_points_protocols.py @@ -2,11 +2,16 @@ import os # Third party imports -from wslink import register as exportRpc +from wslink import register as exportRpc # type: ignore +from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports -from opengeodeweb_viewer.utils_functions import get_schemas_dict, validate_schema +from opengeodeweb_viewer.utils_functions import ( + validate_schema, + RpcParams, +) from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView +from . import schemas class VtkModelPointsView(VtkModelView): @@ -19,19 +24,19 @@ def __init__(self): super().__init__() @exportRpc(model_points_prefix + model_points_schemas_dict["visibility"]["rpc"]) - def setModelPointsVisibility(self, params): + def setModelPointsVisibility(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.model_points_schemas_dict["visibility"], self.model_points_prefix, ) - id, visibility = params["id"], params["visibility"] - self.SetPointsVisibility(id, visibility) + params = schemas.Visibility.from_dict(rpc_params) + self.SetPointsVisibility(params.id, params.visibility) @exportRpc(model_points_prefix + model_points_schemas_dict["size"]["rpc"]) - def setModelPointsSize(self, params): + def setModelPointsSize(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.model_points_schemas_dict["size"], self.model_points_prefix + rpc_params, self.model_points_schemas_dict["size"], self.model_points_prefix ) - id, size = params["id"], params["size"] - self.SetPointsSize(id, size) + params = schemas.Size.from_dict(rpc_params) + self.SetPointsSize(params.id, params.size) diff --git a/src/opengeodeweb_viewer/rpc/model/points/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/model/points/schemas/__init__.py new file mode 100644 index 0000000..76878e5 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/points/schemas/__init__.py @@ -0,0 +1,2 @@ +from .visibility import * +from .size import * diff --git a/src/opengeodeweb_viewer/rpc/model/points/schemas/size.py b/src/opengeodeweb_viewer/rpc/model/points/schemas/size.py new file mode 100644 index 0000000..3ed13eb --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/points/schemas/size.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Size(DataClassJsonMixin): + id: str + size: float diff --git a/src/opengeodeweb_viewer/rpc/model/points/schemas/visibility.py b/src/opengeodeweb_viewer/rpc/model/points/schemas/visibility.py new file mode 100644 index 0000000..78c2b5c --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/points/schemas/visibility.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Visibility(DataClassJsonMixin): + id: str + visibility: bool diff --git a/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py new file mode 100644 index 0000000..a974c1d --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/schemas/__init__.py @@ -0,0 +1,3 @@ +from .visibility import * +from .register import * +from .deregister import * diff --git a/src/opengeodeweb_viewer/rpc/model/schemas/deregister.py b/src/opengeodeweb_viewer/rpc/model/schemas/deregister.py new file mode 100644 index 0000000..f9c0aee --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/schemas/deregister.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Deregister(DataClassJsonMixin): + id: str diff --git a/src/opengeodeweb_viewer/rpc/model/schemas/register.py b/src/opengeodeweb_viewer/rpc/model/schemas/register.py new file mode 100644 index 0000000..e15e699 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/schemas/register.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Register(DataClassJsonMixin): + id: str diff --git a/src/opengeodeweb_viewer/rpc/model/schemas/visibility.py b/src/opengeodeweb_viewer/rpc/model/schemas/visibility.py new file mode 100644 index 0000000..78c2b5c --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/schemas/visibility.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Visibility(DataClassJsonMixin): + id: str + visibility: bool 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 1a73e27..20a985d 100644 --- a/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/model_surfaces_protocols.py @@ -2,11 +2,16 @@ import os # Third party imports -from wslink import register as exportRpc +from wslink import register as exportRpc # type: ignore +from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports -from opengeodeweb_viewer.utils_functions import get_schemas_dict, validate_schema +from opengeodeweb_viewer.utils_functions import ( + validate_schema, + RpcParams, +) from opengeodeweb_viewer.rpc.model.model_protocols import VtkModelView +from . import schemas class VtkModelSurfacesView(VtkModelView): @@ -19,31 +24,22 @@ def __init__(self): super().__init__() @exportRpc(model_surfaces_prefix + model_surfaces_schemas_dict["visibility"]["rpc"]) - def setModelSurfacesPolygonsVisibility(self, params): + def setModelSurfacesPolygonsVisibility(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.model_surfaces_schemas_dict["visibility"], self.model_surfaces_prefix, ) - id, block_ids, visibility = ( - params["id"], - params["block_ids"], - params["visibility"], - ) - self.SetBlocksVisibility(id, block_ids, visibility) + params = schemas.Visibility.from_dict(rpc_params) + self.SetBlocksVisibility(params.id, params.block_ids, params.visibility) @exportRpc(model_surfaces_prefix + model_surfaces_schemas_dict["color"]["rpc"]) - def setModelSurfacesPolygonsCOlor(self, params): + def setModelSurfacesPolygonsCOlor(self, rpc_params: RpcParams) -> None: validate_schema( - params, + rpc_params, self.model_surfaces_schemas_dict["color"], self.model_surfaces_prefix, ) - id, block_ids, red, green, blue = ( - params["id"], - params["block_ids"], - params["color"]["r"], - params["color"]["g"], - params["color"]["b"], - ) - self.SetBlocksColor(id, block_ids, red, green, blue) + params = schemas.Color.from_dict(rpc_params) + color = params.color + self.SetBlocksColor(params.id, params.block_ids, color.r, color.g, color.b) diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/__init__.py new file mode 100644 index 0000000..91183b4 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/__init__.py @@ -0,0 +1,3 @@ +from .visibility import * +from .color import * +from .apply_textures import * diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/apply_textures.py b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/apply_textures.py new file mode 100644 index 0000000..b96e9ee --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/apply_textures.py @@ -0,0 +1,15 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import List + + +@dataclass +class Texture(DataClassJsonMixin): + texture_file_name: str + texture_name: str + + +@dataclass +class ApplyTextures(DataClassJsonMixin): + id: str + textures: List[Texture] diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py new file mode 100644 index 0000000..3c52ca4 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/color.py @@ -0,0 +1,18 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import Optional, List + + +@dataclass +class ColorClass(DataClassJsonMixin): + b: int + g: int + r: int + a: Optional[float] = None + + +@dataclass +class Color(DataClassJsonMixin): + block_ids: List[int] + color: ColorClass + id: str diff --git a/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/visibility.py b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/visibility.py new file mode 100644 index 0000000..0e79ba2 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/model/surfaces/schemas/visibility.py @@ -0,0 +1,10 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import List + + +@dataclass +class Visibility(DataClassJsonMixin): + block_ids: List[int] + id: str + visibility: bool diff --git a/src/opengeodeweb_viewer/rpc/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/schemas/__init__.py new file mode 100644 index 0000000..4452316 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/schemas/__init__.py @@ -0,0 +1 @@ +from .kill import * diff --git a/src/opengeodeweb_viewer/rpc/schemas/kill.py b/src/opengeodeweb_viewer/rpc/schemas/kill.py new file mode 100644 index 0000000..f2c4b04 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/schemas/kill.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Kill(DataClassJsonMixin): + pass diff --git a/src/opengeodeweb_viewer/rpc/utils_protocols.py b/src/opengeodeweb_viewer/rpc/utils_protocols.py index 1511565..6be033a 100644 --- a/src/opengeodeweb_viewer/rpc/utils_protocols.py +++ b/src/opengeodeweb_viewer/rpc/utils_protocols.py @@ -1,25 +1,24 @@ -# type: ignore # Standard library imports import os # Third party imports -from wslink import register as exportRpc +from wslink import register as exportRpc # type: ignore # Local application imports -from opengeodeweb_viewer.utils_functions import get_schemas_dict +from opengeodeweb_microservice.schemas import get_schemas_dict from opengeodeweb_viewer.vtk_protocol import VtkView class VtkUtilsView(VtkView): - ogw_prefix = "opengeodeweb_viewer." - ogw_schemas_dict = get_schemas_dict( + utils_prefix = "opengeodeweb_viewer." + utils_schemas_dict = get_schemas_dict( os.path.join(os.path.dirname(__file__), "schemas") ) def __init__(self) -> None: super().__init__() - @exportRpc(ogw_prefix + ogw_schemas_dict["kill"]["rpc"]) + @exportRpc(utils_prefix + utils_schemas_dict["kill"]["rpc"]) def kill(self) -> None: print("Manual viewer kill, shutting down...", flush=True) os._exit(0) diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py new file mode 100644 index 0000000..1a68349 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/__init__.py @@ -0,0 +1,12 @@ +from .update_data import * +from .update_camera import * +from .take_screenshot import * +from .set_z_scaling import * +from .set_background_color import * +from .reset_visualization import * +from .reset_camera import * +from .render_now import * +from .picked_ids import * +from .grid_scale import * +from .get_point_position import * +from .axes import * diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/axes.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/axes.py new file mode 100644 index 0000000..b1354f5 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/axes.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Axes(DataClassJsonMixin): + visibility: bool diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/get_point_position.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/get_point_position.py new file mode 100644 index 0000000..90c3859 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/get_point_position.py @@ -0,0 +1,8 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class GetPointPosition(DataClassJsonMixin): + x: int + y: int diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/grid_scale.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/grid_scale.py new file mode 100644 index 0000000..e06adc0 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/grid_scale.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class GridScale(DataClassJsonMixin): + visibility: bool diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/picked_ids.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/picked_ids.py new file mode 100644 index 0000000..cff05d3 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/picked_ids.py @@ -0,0 +1,10 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import List + + +@dataclass +class PickedIDS(DataClassJsonMixin): + ids: List[str] + x: float + y: float diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/render_now.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/render_now.py new file mode 100644 index 0000000..2ff9060 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/render_now.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class RenderNow(DataClassJsonMixin): + pass diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/reset_camera.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/reset_camera.py new file mode 100644 index 0000000..f8f9674 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/reset_camera.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class ResetCamera(DataClassJsonMixin): + pass diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/reset_visualization.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/reset_visualization.py new file mode 100644 index 0000000..ca99bd1 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/reset_visualization.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class ResetVisualization(DataClassJsonMixin): + pass diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/set_background_color.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/set_background_color.py new file mode 100644 index 0000000..0302d3b --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/set_background_color.py @@ -0,0 +1,14 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class Color(DataClassJsonMixin): + b: int + g: int + r: int + + +@dataclass +class SetBackgroundColor(DataClassJsonMixin): + color: Color diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/set_z_scaling.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/set_z_scaling.py new file mode 100644 index 0000000..0a0558e --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/set_z_scaling.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class SetZScaling(DataClassJsonMixin): + z_scale: float diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/take_screenshot.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/take_screenshot.py new file mode 100644 index 0000000..c6b7df0 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/take_screenshot.py @@ -0,0 +1,15 @@ +from dataclasses_json import DataClassJsonMixin +from enum import Enum +from dataclasses import dataclass + + +class OutputExtension(Enum): + JPG = "jpg" + PNG = "png" + + +@dataclass +class TakeScreenshot(DataClassJsonMixin): + filename: str + include_background: bool + output_extension: OutputExtension diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/update_camera.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/update_camera.py new file mode 100644 index 0000000..31c470f --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/update_camera.py @@ -0,0 +1,17 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass +from typing import List + + +@dataclass +class CameraOptions(DataClassJsonMixin): + clipping_range: List[float] + focal_point: List[float] + position: List[float] + view_angle: float + view_up: List[float] + + +@dataclass +class UpdateCamera(DataClassJsonMixin): + camera_options: CameraOptions diff --git a/src/opengeodeweb_viewer/rpc/viewer/schemas/update_data.py b/src/opengeodeweb_viewer/rpc/viewer/schemas/update_data.py new file mode 100644 index 0000000..993ac81 --- /dev/null +++ b/src/opengeodeweb_viewer/rpc/viewer/schemas/update_data.py @@ -0,0 +1,7 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class UpdateData(DataClassJsonMixin): + id: str diff --git a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py index bd18e52..5397709 100644 --- a/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py +++ b/src/opengeodeweb_viewer/rpc/viewer/viewer_protocols.py @@ -3,22 +3,30 @@ import os # Third party imports -import vtk +from wslink import register as exportRpc # type: ignore from vtkmodules.vtkIOImage import vtkPNGWriter, vtkJPEGWriter -from vtkmodules.vtkRenderingAnnotation import vtkCubeAxesActor -from vtkmodules.vtkRenderingCore import vtkWindowToImageFilter +from vtkmodules.vtkRenderingAnnotation import vtkCubeAxesActor, vtkAxesActor +from vtkmodules.vtkRenderingCore import ( + vtkWindowToImageFilter, + vtkRenderer, + vtkRenderWindowInteractor, + vtkAbstractMapper, + vtkWorldPointPicker, +) +from vtkmodules.vtkInteractionStyle import vtkInteractorStyleTrackball +from vtkmodules.vtkCommonCore import reference +from vtkmodules.vtkCommonDataModel import vtkBoundingBox from vtkmodules.vtkCommonTransforms import vtkTransform -from wslink import register as exportRpc +from vtkmodules.vtkInteractionWidgets import vtkOrientationMarkerWidget +from opengeodeweb_microservice.schemas import get_schemas_dict # Local application imports from opengeodeweb_viewer.utils_functions import ( - get_schemas_dict, validate_schema, RpcParams, - RpcParamsWithColor, - RpcParamsWithList, ) from opengeodeweb_viewer.vtk_protocol import VtkView +from . import schemas class VtkViewerView(VtkView): @@ -31,9 +39,11 @@ def __init__(self) -> None: super().__init__() @exportRpc(viewer_prefix + viewer_schemas_dict["reset_visualization"]["rpc"]) - def resetVisualization(self, params: RpcParams) -> None: + def resetVisualization(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.viewer_schemas_dict["reset_visualization"], self.viewer_prefix + rpc_params, + self.viewer_schemas_dict["reset_visualization"], + self.viewer_prefix, ) renderWindow = self.getView("-1") renderer = renderWindow.GetRenderers().GetFirstRenderer() @@ -60,24 +70,25 @@ def resetVisualization(self, params: RpcParams) -> None: grid_scale.SetFlyModeToOuterEdges() grid_scale.SetVisibility(False) - self.register_object("grid_scale", "", "", grid_scale, "", "") + self.set_grid_scale(grid_scale) renderer.AddActor(grid_scale) - renderWindowInteractor = vtk.vtkRenderWindowInteractor() + renderWindowInteractor = vtkRenderWindowInteractor() renderWindowInteractor.SetRenderWindow(renderWindow) - renderWindowInteractor.GetInteractorStyle().SetCurrentStyleToTrackballCamera() + style = vtkInteractorStyleTrackball() + renderWindowInteractor.SetInteractorStyle(style) renderWindowInteractor.EnableRenderOff() - widget = vtk.vtkOrientationMarkerWidget() + widget = vtkOrientationMarkerWidget() widget.SetInteractor(renderWindowInteractor) widget.SetViewport(0.8, 0.0, 1, 0.2) - axes = vtk.vtkAxesActor() + axes = vtkAxesActor() widget.SetOrientationMarker(axes) widget.EnabledOn() widget.InteractiveOff() - self.register_object("axes", "", "", axes, "", "") - self.register_object("widget", "", "", widget, "", "") + self.set_axes(axes) + self.set_widget(widget) renderer.SetBackground([180 / 255, 180 / 255, 180 / 255]) @@ -86,27 +97,26 @@ def resetVisualization(self, params: RpcParams) -> None: self.render() @exportRpc(viewer_prefix + viewer_schemas_dict["set_background_color"]["rpc"]) - def setBackgroundColor(self, params: RpcParamsWithColor) -> None: + def setBackgroundColor(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.viewer_schemas_dict["set_background_color"], self.viewer_prefix - ) - red, green, blue = ( - params["color"]["r"], - params["color"]["g"], - params["color"]["b"], + rpc_params, + self.viewer_schemas_dict["set_background_color"], + self.viewer_prefix, ) + params = schemas.SetBackgroundColor.from_dict(rpc_params) + color = params.color renderWindow = self.getView("-1") renderer = renderWindow.GetRenderers().GetFirstRenderer() - renderer.SetBackground([red / 255, green / 255, blue / 255]) + renderer.SetBackground([color.r / 255, color.g / 255, color.b / 255]) renderer.ResetCamera() renderWindow.Render() self.render() @exportRpc(viewer_prefix + viewer_schemas_dict["reset_camera"]["rpc"]) - def resetCamera(self, params: RpcParams) -> None: + def resetCamera(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.viewer_schemas_dict["reset_camera"], self.viewer_prefix + rpc_params, self.viewer_schemas_dict["reset_camera"], self.viewer_prefix ) renderWindow = self.getView("-1") renderWindow.GetRenderers().GetFirstRenderer().ResetCamera() @@ -114,21 +124,16 @@ def resetCamera(self, params: RpcParams) -> None: self.render() @exportRpc(viewer_prefix + viewer_schemas_dict["take_screenshot"]["rpc"]) - def takeScreenshot(self, params: RpcParams) -> dict[str, str | bytes]: + def takeScreenshot(self, rpc_params: RpcParams) -> dict[str, str | bytes]: validate_schema( - params, self.viewer_schemas_dict["take_screenshot"], self.viewer_prefix - ) - - filename, output_extension, include_background = ( - params["filename"], - params["output_extension"], - params["include_background"], + rpc_params, self.viewer_schemas_dict["take_screenshot"], self.viewer_prefix ) + params = schemas.TakeScreenshot.from_dict(rpc_params) renderWindow = self.getView("-1") renderer = self.get_renderer() w2if = vtkWindowToImageFilter() - + include_background = params.include_background if not include_background: renderWindow.SetAlphaBitPlanes(1) w2if.SetInputBufferTypeToRGBA() @@ -141,17 +146,17 @@ def takeScreenshot(self, params: RpcParams) -> dict[str, str | bytes]: w2if.SetInput(renderWindow) w2if.ReadFrontBufferOff() w2if.Update() - - if output_extension == "png": + output_extension = params.output_extension + if output_extension == schemas.OutputExtension.PNG: writer = vtkPNGWriter() - elif output_extension in ["jpg", "jpeg"]: + elif output_extension == schemas.OutputExtension.JPG: if not include_background: raise Exception("output_extension not supported with background") writer = vtkJPEGWriter() else: raise Exception("output_extension not supported") - new_filename = filename + "." + output_extension + new_filename = params.filename + "." + output_extension.value file_path = os.path.join(self.DATA_FOLDER_PATH, new_filename) writer.SetFileName(file_path) writer.SetInputConnection(w2if.GetOutputPort()) @@ -163,18 +168,17 @@ def takeScreenshot(self, params: RpcParams) -> dict[str, str | bytes]: return {"blob": self.addAttachment(file_content)} @exportRpc(viewer_prefix + viewer_schemas_dict["update_data"]["rpc"]) - def updateData(self, params: RpcParams) -> None: + def updateData(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.viewer_schemas_dict["update_data"], self.viewer_prefix + rpc_params, self.viewer_schemas_dict["update_data"], self.viewer_prefix ) - id = params["id"] - - data = self.get_object(id) + params = schemas.UpdateData.from_dict(rpc_params) + data = self.get_object(params.id) reader = data["reader"] reader.Update() mapper = data["mapper"] - tag = vtk.reference(0) - scalars = vtk.vtkAbstractMapper.GetAbstractScalars( + tag = reference(0) + scalars = vtkAbstractMapper.GetAbstractScalars( reader.GetOutput(), mapper.GetScalarMode(), mapper.GetArrayAccessMode(), @@ -186,19 +190,20 @@ def updateData(self, params: RpcParams) -> None: self.render() @exportRpc(viewer_prefix + viewer_schemas_dict["get_point_position"]["rpc"]) - def getPointPosition(self, params: RpcParams) -> dict[str, float]: + def getPointPosition(self, rpc_params: RpcParams) -> dict[str, float]: validate_schema( - params, self.viewer_schemas_dict["get_point_position"], self.viewer_prefix + rpc_params, + self.viewer_schemas_dict["get_point_position"], + self.viewer_prefix, ) - x = float(params["x"]) - y = float(params["y"]) - xyz = [x, y, 0.0] - picker = vtk.vtkWorldPointPicker() + params = schemas.GetPointPosition.from_dict(rpc_params) + xyz = [params.x, params.y, 0.0] + picker = vtkWorldPointPicker() picker.Pick(xyz, self.get_renderer()) ppos = picker.GetPickPosition() return {"x": ppos[0], "y": ppos[1], "z": ppos[2]} - def computeEpsilon(self, renderer: vtk.vtkRenderer, z: float) -> float: + def computeEpsilon(self, renderer: vtkRenderer, z: float) -> float: renderer.SetDisplayPoint(0, 0, z) renderer.DisplayToWorld() windowLowerLeft = renderer.GetWorldPoint() @@ -214,92 +219,89 @@ def computeEpsilon(self, renderer: vtk.vtkRenderer, z: float) -> float: return math.sqrt(epsilon) * 0.0125 @exportRpc(viewer_prefix + viewer_schemas_dict["picked_ids"]["rpc"]) - def pickedIds(self, params: RpcParamsWithList) -> dict[str, list[str]]: + def pickedIds(self, rpc_params: RpcParams) -> dict[str, list[str]]: validate_schema( - params, self.viewer_schemas_dict["picked_ids"], self.viewer_prefix + rpc_params, self.viewer_schemas_dict["picked_ids"], self.viewer_prefix ) - x, y, ids = params["x"], params["y"], params["ids"] - + params = schemas.PickedIDS.from_dict(rpc_params) renderWindow = self.getView("-1") renderer = renderWindow.GetRenderers().GetFirstRenderer() - picker = vtk.vtkWorldPointPicker() - picker.Pick([x, y, 0], renderer) + picker = vtkWorldPointPicker() + picker.Pick([params.x, params.y, 0], renderer) point = picker.GetPickPosition() epsilon = self.computeEpsilon(renderer, point[2]) - bbox = vtk.vtkBoundingBox() + bbox = vtkBoundingBox() bbox.AddPoint(point[0] + epsilon, point[1] + epsilon, point[2] + epsilon) bbox.AddPoint(point[0] - epsilon, point[1] - epsilon, point[2] - epsilon) array_ids = [] - for id in ids: - bounds = self.get_object(id)["actor"].GetBounds() + for id in params.ids: + bounds = self.get_object(id).actor.GetBounds() if bbox.Intersects(bounds): array_ids.append(id) return {"array_ids": array_ids} @exportRpc(viewer_prefix + viewer_schemas_dict["grid_scale"]["rpc"]) - def toggleGridScale(self, params: RpcParams) -> None: + def toggleGridScale(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.viewer_schemas_dict["grid_scale"], self.viewer_prefix + rpc_params, self.viewer_schemas_dict["grid_scale"], self.viewer_prefix ) - id, visibility = "grid_scale", params["visibility"] - if "grid_scale" in self.get_data_base(): - actor = self.get_object(id)["actor"] - actor.SetVisibility(visibility) + params = schemas.GridScale.from_dict(rpc_params) + grid_scale = self.get_grid_scale() + if grid_scale is not None: + grid_scale.SetVisibility(params.visibility) self.render() @exportRpc(viewer_prefix + viewer_schemas_dict["axes"]["rpc"]) - def toggleAxes(self, params: RpcParams) -> None: - validate_schema(params, self.viewer_schemas_dict["axes"], self.viewer_prefix) - id, visibility = "axes", params["visibility"] - actor = self.get_object(id)["actor"] - actor.SetVisibility(visibility) + def toggleAxes(self, rpc_params: RpcParams) -> None: + validate_schema( + rpc_params, self.viewer_schemas_dict["axes"], self.viewer_prefix + ) + params = schemas.Axes.from_dict(rpc_params) + axes = self.get_axes() + if axes is not None: + axes.SetVisibility(params.visibility) self.render() @exportRpc(viewer_prefix + viewer_schemas_dict["update_camera"]["rpc"]) - def updateCamera(self, params: RpcParams) -> None: + def updateCamera(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.viewer_schemas_dict["update_camera"], self.viewer_prefix + rpc_params, self.viewer_schemas_dict["update_camera"], self.viewer_prefix ) - camera_options = params["camera_options"] - focal_point = camera_options["focal_point"] - view_up = camera_options["view_up"] - position = camera_options["position"] - view_angle = camera_options["view_angle"] - clipping_range = camera_options["clipping_range"] + params = schemas.UpdateCamera.from_dict(rpc_params) + camera_options = params.camera_options renderWindow = self.getView("-1") camera = renderWindow.GetRenderers().GetFirstRenderer().GetActiveCamera() - camera.SetFocalPoint(*focal_point) - camera.SetViewUp(*view_up) - camera.SetPosition(*position) - camera.SetViewAngle(view_angle) - camera.SetClippingRange(*clipping_range) + camera.SetFocalPoint(camera_options.focal_point) + camera.SetViewUp(camera_options.view_up) + camera.SetPosition(camera_options.position) + camera.SetViewAngle(camera_options.view_angle) + camera.SetClippingRange(camera_options.clipping_range) self.render() @exportRpc(viewer_prefix + viewer_schemas_dict["render_now"]["rpc"]) - def renderNow(self, params: RpcParams) -> None: + def renderNow(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.viewer_schemas_dict["render_now"], self.viewer_prefix + rpc_params, self.viewer_schemas_dict["render_now"], self.viewer_prefix ) self.render() @exportRpc(viewer_prefix + viewer_schemas_dict["set_z_scaling"]["rpc"]) - def setZScaling(self, params: RpcParams) -> None: + def setZScaling(self, rpc_params: RpcParams) -> None: validate_schema( - params, self.viewer_schemas_dict["set_z_scaling"], self.viewer_prefix + rpc_params, self.viewer_schemas_dict["set_z_scaling"], self.viewer_prefix ) - z_scale = params["z_scale"] + params = schemas.SetZScaling.from_dict(rpc_params) renderWindow = self.getView("-1") renderer = renderWindow.GetRenderers().GetFirstRenderer() cam = renderer.GetActiveCamera() - transform = vtk.vtkTransform() - transform.Scale(1, 1, z_scale) + transform = vtkTransform() + transform.Scale(1, 1, params.z_scale) cam.SetModelTransformMatrix(transform.GetMatrix()) - - if "grid_scale" in self.get_data_base(): - cube_axes_actor = self.get_object("grid_scale")["actor"] - cube_axes_actor.SetUse2DMode(1) + grid_scale = self.get_grid_scale() + if grid_scale is not None: + grid_scale.SetUse2DMode(True) self.render() diff --git a/src/opengeodeweb_viewer/utils_functions.py b/src/opengeodeweb_viewer/utils_functions.py index 0829366..f2c468d 100644 --- a/src/opengeodeweb_viewer/utils_functions.py +++ b/src/opengeodeweb_viewer/utils_functions.py @@ -1,39 +1,20 @@ # Standard library imports -import os -import json # Third party imports -import fastjsonschema -from fastjsonschema import JsonSchemaException +import fastjsonschema # type: ignore -type JsonPrimitive = str | int | float | bool -type JsonValue = JsonPrimitive | dict[str, JsonValue] | list[JsonValue] -type RpcParams = dict[str, JsonValue] +from opengeodeweb_microservice.schemas import SchemaDict -type ColorDict = dict[str, int] -type RpcParamsWithColor = dict[str, JsonPrimitive | ColorDict] -type RpcParamsWithList = dict[str, JsonPrimitive | list[str]] - - -def get_schemas_dict(path: str) -> dict[str, dict[str, JsonValue]]: - json_files = os.listdir(path) - schemas_dict: dict[str, dict[str, JsonValue]] = {} - for json_file in json_files: - last_point = json_file.rfind(".") - filename = json_file[: -len(json_file) + last_point] - with open(os.path.join(path, json_file), "r") as file: - file_content = json.load(file) - schemas_dict[filename] = file_content - return schemas_dict +type RpcParams = dict[str, str] def validate_schema( - params: RpcParams, schema: dict[str, JsonValue], prefix: str = "" + rpc_params: RpcParams, schema: SchemaDict, prefix: str = "" ) -> None: - print(f"{prefix}{schema['rpc']}", f"{params=}", flush=True) + print(f"{prefix}{schema['rpc']}", f"{rpc_params=}", flush=True) try: validate = fastjsonschema.compile(schema) - validate(params) + validate(rpc_params) except fastjsonschema.JsonSchemaException as e: print(f"Validation error: {e.message}", flush=True) raise Exception( diff --git a/src/opengeodeweb_viewer/vtk_protocol.py b/src/opengeodeweb_viewer/vtk_protocol.py index cd5bb96..4bf34ea 100644 --- a/src/opengeodeweb_viewer/vtk_protocol.py +++ b/src/opengeodeweb_viewer/vtk_protocol.py @@ -1,29 +1,67 @@ # Standard library imports import os +from typing import cast, Any, Literal +from dataclasses import dataclass, field # Third party imports -import vtk -from vtk.web import protocols as vtk_protocols # type: ignore +import vtkmodules.vtkRenderingOpenGL2 +from vtkmodules.web import protocols as vtk_protocols +from vtkmodules.vtkIOXML import ( + vtkXMLReader, +) +from vtkmodules.vtkCommonExecutionModel import vtkAlgorithm +from vtkmodules.vtkRenderingCore import ( + vtkActor, + vtkMapper, + vtkRenderer, +) +from vtkmodules.vtkRenderingAnnotation import vtkCubeAxesActor, vtkAxesActor +from vtkmodules.vtkInteractionWidgets import vtkOrientationMarkerWidget # Local application imports from opengeodeweb_microservice.database.connection import get_session from opengeodeweb_microservice.database.data import Data -# mypy: allow-untyped-defs + +@dataclass +class vtkData: + reader: vtkXMLReader + mapper: vtkMapper + filter: vtkAlgorithm | None = None + actor: vtkActor = field(default_factory=vtkActor) + max_dimension: Literal["points", "edges", "polygons", "polyhedra", "default"] = ( + "default" + ) class VtkView(vtk_protocols.vtkWebProtocol): def __init__(self) -> None: super().__init__() - self.DATA_FOLDER_PATH = os.getenv("DATA_FOLDER_PATH") - self.DataReader = vtk.vtkXMLPolyDataReader() - self.ImageReader = vtk.vtkXMLImageDataReader() + self.DATA_FOLDER_PATH = os.getenv("DATA_FOLDER_PATH", ".") - def get_data_base(self) -> dict[str, dict[str, object | str]]: + def get_data_base(self) -> Any: return self.getSharedObject("db") - def get_object(self, id: str) -> dict[str, object | str]: - return self.get_data_base()[id] + def get_object(self, id: str) -> vtkData: + return cast(vtkData, self.get_data_base()[id]) + + def get_grid_scale(self) -> vtkCubeAxesActor | None: + return cast(vtkCubeAxesActor | None, self.getSharedObject("grid_scale")) + + def set_grid_scale(self, grid_scale: vtkCubeAxesActor) -> None: + self.coreServer.setSharedObject("grid_scale", grid_scale) + + def get_axes(self) -> vtkAxesActor | None: + return cast(vtkAxesActor | None, self.getSharedObject("axes")) + + def set_axes(self, axes: vtkAxesActor) -> None: + self.coreServer.setSharedObject("axes", axes) + + def get_widget(self) -> vtkOrientationMarkerWidget | None: + return cast(vtkOrientationMarkerWidget | None, self.getSharedObject("widget")) + + def set_widget(self, widget: vtkOrientationMarkerWidget) -> None: + self.coreServer.setSharedObject("widget", widget) def get_viewer_object_type(self, data_id: str) -> str: data = self.get_data(data_id) @@ -68,38 +106,19 @@ def get_data_file_path(self, data_id: str, filename: str | None = None) -> str: return os.path.join(data_folder_path, data_id, filename) - def get_renderer(self) -> vtk.vtkRenderer: - return self.getSharedObject("renderer") - - def get_protocol(self, name: str) -> vtk_protocols.vtkWebProtocol: - for p in self.coreServer.getLinkProtocols(): - if type(p).__name__ == name: - return p + def get_renderer(self) -> vtkRenderer: + return cast(vtkRenderer, self.getSharedObject("renderer")) def render(self, view: int = -1) -> None: - if "grid_scale" in self.get_data_base(): + grid_scale = self.get_grid_scale() + if grid_scale is not None: renderer = self.get_renderer() renderer_bounds = renderer.ComputeVisiblePropBounds() - grid_scale = self.get_object("grid_scale")["actor"] grid_scale.SetBounds(renderer_bounds) self.getSharedObject("publisher").imagePush({"view": view}) - def register_object( - self, - id: str, - reader: vtk.vtkAlgorithm, - filter: vtk.vtkAlgorithm, - actor: vtk.vtkActor, - mapper: vtk.vtkMapper, - textures: dict[str, str | int | float], - ) -> None: - self.get_data_base()[id] = { - "reader": reader, - "filter": filter, - "actor": actor, - "mapper": mapper, - "textures": textures, - } + def register_object(self, id: str, data: vtkData) -> None: + self.get_data_base()[id] = data def deregister_object(self, id: str) -> None: if id in self.get_data_base(): diff --git a/src/opengeodeweb_viewer/vtkw_server.py b/src/opengeodeweb_viewer/vtkw_server.py index f3aa803..0ca551b 100644 --- a/src/opengeodeweb_viewer/vtkw_server.py +++ b/src/opengeodeweb_viewer/vtkw_server.py @@ -3,10 +3,10 @@ import os # Third party imports -import vtk -from vtk.web import wslink as vtk_wslink -from vtk.web import protocols as vtk_protocols -from wslink import server +from vtkmodules.web import wslink as vtk_wslink +from vtkmodules.web import protocols as vtk_protocols +from wslink import server # type: ignore +from vtkmodules.vtkRenderingCore import vtkRenderer, vtkRenderWindow from opengeodeweb_microservice.database import connection # Local application imports @@ -38,7 +38,7 @@ VtkModelBlocksView, ) from .rpc.generic.generic_protocols import VtkGenericView -from .rpc.utils_protocols import VtkUtilsView # type: ignore +from .rpc.utils_protocols import VtkUtilsView # ============================================================================= @@ -104,8 +104,8 @@ def initialize(self): self.updateSecret(_Server.authKey) if not _Server.view: - renderer = vtk.vtkRenderer() - renderWindow = vtk.vtkRenderWindow() + renderer = vtkRenderer() + renderWindow = vtkRenderWindow() renderWindow.AddRenderer(renderer) self.setSharedObject("renderer", renderer) self.getApplication().GetObjectIdMap().SetActiveObject("VIEW", renderWindow) diff --git a/tests/conftest.py b/tests/conftest.py index 0491dec..8b7af11 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,7 +3,8 @@ from websocket import create_connection, WebSocketTimeoutException import json from xprocess import ProcessStarter -import vtk +from vtkmodules.vtkIOImage import vtkImageReader2, vtkPNGReader, vtkJPEGReader +from vtkmodules.vtkImagingCore import vtkImageDifference import os import shutil import xml.etree.ElementTree as ET @@ -69,28 +70,28 @@ def get_response(self) -> bytes | dict[str, object] | str: return str(response) @staticmethod - def _reader_for_file(path: str) -> vtk.vtkImageReader2: + def _reader_for_file(path: str) -> vtkImageReader2: lower = path.lower() if lower.endswith(".png"): - return vtk.vtkPNGReader() + return vtkPNGReader() if lower.endswith(".jpg") or lower.endswith(".jpeg"): - return vtk.vtkJPEGReader() - return vtk.vtkJPEGReader() + return vtkJPEGReader() + return vtkJPEGReader() def images_diff(self, first_image_path: str, second_image_path: str) -> float: if ".png" in first_image_path: - first_reader = vtk.vtkPNGReader() + first_reader = vtkPNGReader() elif (".jpg" in first_image_path) or (".jpeg" in first_image_path): - first_reader = vtk.vtkJPEGReader() + first_reader = vtkJPEGReader() first_reader.SetFileName(first_image_path) if ".png" in second_image_path: - second_reader = vtk.vtkPNGReader() + second_reader = vtkPNGReader() elif (".jpg" in second_image_path) or (".jpeg" in second_image_path): - second_reader = vtk.vtkJPEGReader() + second_reader = vtkJPEGReader() second_reader.SetFileName(second_image_path) - images_diff = vtk.vtkImageDifference() + images_diff = vtkImageDifference() images_diff.SetInputConnection(first_reader.GetOutputPort()) images_diff.SetImageConnection(second_reader.GetOutputPort()) images_diff.Update()