From 4f65e9a3de853190e5e4b0fa6c9aa188f5b48671 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Fri, 14 Nov 2025 22:36:26 +0100 Subject: [PATCH 01/21] wip --- .vscode/settings.json | 2 +- src/opengeodeweb_back/geode_functions.py | 185 +-- src/opengeodeweb_back/geode_objects.py | 1193 +++++++++-------- .../geode_objects/geode_brep.py | 43 + .../geode_objects_and_output_extensions.py | 2 +- .../schemas/geographic_coordinate_systems.py | 2 +- .../routes/schemas/inspect_file.py | 2 +- .../routes/schemas/missing_files.py | 2 +- .../routes/schemas/save_viewable_file.py | 2 +- src/opengeodeweb_back/utils_functions.py | 6 +- 10 files changed, 736 insertions(+), 703 deletions(-) create mode 100644 src/opengeodeweb_back/geode_objects/geode_brep.py diff --git a/.vscode/settings.json b/.vscode/settings.json index 006e581e..95f9b2e4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,6 +8,6 @@ "--config-file=mypy.ini" ], "mypy-type-checker.interpreter": [ - "${workspaceFolder}/venv/bin/python" + "${workspaceFolder}/../../.venv/bin/python" ] } \ No newline at end of file diff --git a/src/opengeodeweb_back/geode_functions.py b/src/opengeodeweb_back/geode_functions.py index c9e8fbbd..90e86ef6 100644 --- a/src/opengeodeweb_back/geode_functions.py +++ b/src/opengeodeweb_back/geode_functions.py @@ -2,60 +2,27 @@ import os # Third party imports -import opengeode_geosciences as og_gs # type: ignore -import opengeode as og # type: ignore +import opengeode_geosciences as og_gs +import opengeode as og import werkzeug import flask from typing import Any # Local application imports -from .geode_objects import geode_objects_dict +from .geode_objects import geode_objects,GeodeType, GeodeObject, to_geode_type from . import utils_functions from opengeodeweb_microservice.database.data import Data from opengeodeweb_microservice.database.connection import get_session - -def geode_object_value(geode_object: str): - return geode_objects_dict()[geode_object] - - -def geode_object_class(geode_object: str): - return geode_object_value(geode_object)["class"] - - -def input_factory(geode_object: str): - return geode_object_value(geode_object)["input_factory"] - - -def output_factory(geode_object: str): - return geode_object_value(geode_object)["output_factory"] - - -def additional_files(geode_object: str, file_absolute_path: str): - return geode_object_value(geode_object)["additional_files"](file_absolute_path) - - -def is_loadable(geode_object: str, file_absolute_path: str) -> float: - percentage = geode_object_value(geode_object)["is_loadable"](file_absolute_path) - return percentage.value() - - -def object_priority(geode_object: str, file_absolute_path: str) -> int: - return geode_object_value(geode_object)["object_priority"](file_absolute_path) - - -def load(geode_object: str, file_absolute_path: str): - return geode_object_value(geode_object)["load"](file_absolute_path) - - -def data_file_path(data_id: str, filename: str = "") -> str: +def data_file_path(data_id: str, filename: str | None) -> str: data_folder_path = flask.current_app.config["DATA_FOLDER_PATH"] - if filename: - return os.path.join(data_folder_path, data_id, filename) - return os.path.join(data_folder_path, data_id) + data_path = os.path.join(data_folder_path, data_id) + if filename is not None: + return os.path.join(data_path, filename) + return data_path -def load_data(data_id: str) -> Any: +def load_data(data_id: str) -> GeodeObject: data_entry = Data.get(data_id) if not data_entry: flask.abort(404, f"Data with id {data_id} not found") @@ -63,7 +30,7 @@ def load_data(data_id: str) -> Any: file_absolute_path = data_file_path(data_id, data_entry.native_file_name) print("Loading file: ", file_absolute_path) print("File exists: ", os.path.exists(file_absolute_path)) - return load(data_entry.geode_object, file_absolute_path) + return geode_objects[to_geode_type(data_entry.geode_object)].load(file_absolute_path) def get_data_info(data_id: str) -> Data: @@ -79,114 +46,54 @@ def upload_file_path(filename: str) -> str: return os.path.abspath(os.path.join(upload_folder, secure_filename)) -def is_saveable(geode_object: str, data, filename: str): - return geode_object_value(geode_object)["is_saveable"](data, filename) - - -def save(geode_object: str, data, folder_absolute_path: str, filename: str): - return geode_object_value(geode_object)["save"]( - data, os.path.join(folder_absolute_path, filename) - ) - - -def create_builder(geode_object: str, data): - return geode_object_value(geode_object)["builder"](data) +# def assign_crs(geode_type: GeodeType, data, crs_name: str, info): +# builder = create_builder(geode_object, data) +# geode_objects[geode_type].["crs"]["assign"](data, builder, crs_name, info) -def assign_crs(geode_object: str, data, crs_name: str, info): - builder = create_builder(geode_object, data) - geode_object_value(geode_object)["crs"]["assign"](data, builder, crs_name, info) +# def convert_crs(geode_type: GeodeType, data, crs_name: str, info): +# builder = create_builder(geode_object, data) +# geode_objects[geode_type].["crs"]["convert"](data, builder, crs_name, info) -def convert_crs(geode_object: str, data, crs_name: str, info): - builder = create_builder(geode_object, data) - geode_object_value(geode_object)["crs"]["convert"](data, builder, crs_name, info) +# def create_crs( +# geode_type: GeodeType, +# data, +# name: str, +# input_coordiante_system, +# output_coordiante_system, +# ): +# builder = create_builder(geode_object, data) +# geode_objects[geode_type].["crs"]["create"]( +# data, builder, name, input_coordiante_system, output_coordiante_system +# ) -def create_crs( - geode_object: str, - data, - name: str, - input_coordiante_system, - output_coordiante_system, -): - builder = create_builder(geode_object, data) - geode_object_value(geode_object)["crs"]["create"]( - data, builder, name, input_coordiante_system, output_coordiante_system - ) - - -def get_object_type(geode_object: str): - return geode_object_value(geode_object)["object_type"] - - -def get_elements(geode_object: str): - return geode_object_value(geode_object)["elements"] - - -def is_3D(geode_object: str): - return geode_object_value(geode_object)["is_3D"] - - -def is_viewable(geode_object: str): - return geode_object_value(geode_object)["is_viewable"] - - -def inspect(geode_object: str, data): - return geode_object_value(geode_object)["inspector"](data) - - -def save_viewable(geode_object: str, data, folder_absolute_path: str, id: str): - return geode_object_value(geode_object)["save_viewable"]( - data, os.path.join(folder_absolute_path, id) - ) - - -def save_light_viewable(geode_object: str, data, folder_absolute_path: str, id: str): - return geode_object_value(geode_object)["save_light_viewable"]( - data, os.path.join(folder_absolute_path, id) - ) - - -def geode_object_input_extensions(geode_object: str): - geode_object_input_list_creators = input_factory(geode_object).list_creators() - geode_object_input_list_creators.sort() - return geode_object_input_list_creators - - -def geode_object_output_extensions(geode_object: str): - geode_object_output_list_creators = output_factory(geode_object).list_creators() - geode_object_output_list_creators.sort() - return geode_object_output_list_creators - - -def filter_geode_objects(key: str = None): - geode_objects_filtered_list = [] - for geode_object, value in geode_objects_dict().items(): +def filter_geode_objects(key: str | None = None)-> list[GeodeType]: + filtered_geode_objects = [] + for geode_object, value in geode_objects.items(): if key != None and key != "": if key in value: if type(value[key]) == bool: - geode_objects_filtered_list.append(geode_object) + filtered_geode_objects.append(geode_object) else: - geode_objects_filtered_list.append(geode_object) + filtered_geode_objects.append(geode_object) else: - geode_objects_filtered_list.append(geode_object) - geode_objects_filtered_list.sort() - return geode_objects_filtered_list + filtered_geode_objects.append(geode_object) + filtered_geode_objects.sort() + return filtered_geode_objects def list_input_extensions(key: str | None = None) -> list[str]: extensions_list = [] - geode_objects_filtered_list = filter_geode_objects(key) - for geode_object in geode_objects_filtered_list: + for geode_object in filter_geode_objects(key): extensions_list += geode_object_input_extensions(geode_object) - extensions_list = list(set(extensions_list)) extensions_list.sort() return extensions_list -def has_creator(geode_object: str, extension: str): +def has_creator(geode_type: GeodeType, extension: str): return input_factory(geode_object).has_creator(extension) @@ -210,7 +117,7 @@ def list_geode_objects( return return_dict -def geode_objects_output_extensions(geode_object: str, data): +def geode_objects_output_extensions(geode_type: GeodeType, data): geode_objects_output_extensions_dict = {} output_extensions = geode_object_output_extensions(geode_object) extensions_dict = {} @@ -219,8 +126,8 @@ def geode_objects_output_extensions(geode_object: str, data): extensions_dict[output_extension] = {"is_saveable": bool_is_saveable} geode_objects_output_extensions_dict[geode_object] = extensions_dict - if "parent" in geode_object_value(geode_object).keys(): - parent_geode_object = geode_object_value(geode_object)["parent"] + if "parent" in geode_objects[geode_type]..keys(): + parent_geode_object = geode_objects[geode_type].["parent"] geode_objects_output_extensions_dict.update( geode_objects_output_extensions(parent_geode_object, data) ) @@ -253,14 +160,14 @@ def get_inspector_children(obj): return new_object -def geographic_coordinate_systems(geode_object: str): +def geographic_coordinate_systems(geode_type: GeodeType): if is_3D(geode_object): return og_gs.GeographicCoordinateSystem3D.geographic_coordinate_systems() else: return og_gs.GeographicCoordinateSystem2D.geographic_coordinate_systems() -def geographic_coordinate_systems_info(geode_object: str, crs): +def geographic_coordinate_systems_info(geode_type: GeodeType, crs): if is_3D(geode_object): return og_gs.GeographicCoordinateSystemInfo3D( crs["authority"], crs["code"], crs["name"] @@ -271,7 +178,7 @@ def geographic_coordinate_systems_info(geode_object: str, crs): ) -def coordinate_system(geode_object: str, coordinate_system): +def coordinate_system(geode_type: GeodeType, coordinate_system): return og.CoordinateSystem2D( [ og.Vector2D( @@ -295,18 +202,18 @@ def coordinate_system(geode_object: str, coordinate_system): ) -def assign_geographic_coordinate_system_info(geode_object: str, data, input_crs): +def assign_geographic_coordinate_system_info(geode_type: GeodeType, data, input_crs): info = geographic_coordinate_systems_info(geode_object, input_crs) assign_crs(geode_object, data, input_crs["name"], info) -def convert_geographic_coordinate_system_info(geode_object: str, data, output_crs): +def convert_geographic_coordinate_system_info(geode_type: GeodeType, data, output_crs): info = geographic_coordinate_systems_info(geode_object, output_crs) convert_crs(geode_object, data, output_crs["name"], info) def create_coordinate_system( - geode_object: str, data, name, input_coordinate_points, output_coordinate_points + geode_type: GeodeType, data, name, input_coordinate_points, output_coordinate_points ): input_coordiante_system = coordinate_system(geode_object, input_coordinate_points) output_coordiante_system = coordinate_system(geode_object, output_coordinate_points) diff --git a/src/opengeodeweb_back/geode_objects.py b/src/opengeodeweb_back/geode_objects.py index 596011b3..5e7a84bb 100644 --- a/src/opengeodeweb_back/geode_objects.py +++ b/src/opengeodeweb_back/geode_objects.py @@ -1,14 +1,96 @@ # Standard library imports +from abc import ABC, abstractmethod +from typing import Literal, Any, get_args, cast +from __future__ import annotations # Third party imports -import opengeode as og # type: ignore -import opengeode_io as og_io # type: ignore -import opengeode_inspector as og_inspector # type: ignore -import opengeode_geosciences as og_gs # type: ignore -import opengeode_geosciencesio as og_gs_io # type: ignore -import geode_viewables as g_v # type: ignore +import opengeode as og +import opengeode_io as og_io +import opengeode_inspector as og_inspector +import opengeode_geosciences as og_gs +import opengeode_geosciencesio as og_gs_io +import geode_viewables as viewables # Local application imports +from .geode_objects.geode_brep import GeodeBRep + + +GeodeType = Literal["BRep"] + +def to_geode_type(value: str) -> GeodeType: + allowed = get_args(GeodeType) + if value not in allowed: + raise ValueError(f"Invalid GeodeType: {value!r}. Must be one of {allowed}") + return cast(GeodeType, value) + +ViewerType = Literal["mesh", "model"] + + +class GeodeObject(ABC): + geode_type: GeodeType + object_type: ViewerType + is_3D: bool + is_viewable: bool + + def __init__(self, geode_type: GeodeType, object_type: ViewerType, is_3D: bool = True, is_viewable: bool = True) -> None: + self.object_type = object_type + self.is_3D = is_3D + self.is_viewable = is_viewable + + @abstractmethod + def builder(self) -> Any: + ... + + @classmethod + @abstractmethod + def load(self, filename: str) -> GeodeObject: + ... + + @classmethod + @abstractmethod + def additional_files(cls, filename: str) -> Any: + ... + + @classmethod + @abstractmethod + def is_loadable(cls, filename: str) -> og.Percentage: + ... + + @classmethod + @abstractmethod + def input_extensions(cls) -> list[str]: + ... + + @classmethod + @abstractmethod + def object_priority(cls, filename: str) -> int: + ... + + @classmethod + @abstractmethod + def output_extensions(cls) -> list[str]: + ... + + @abstractmethod + def is_saveable(self, filename: str) -> bool: + ... + + @abstractmethod + def save(self, filename: str) -> list[str]: + ... + + @abstractmethod + def save_viewable(self, filename_without_extension: str) -> str: + ... + + @abstractmethod + def save_light_viewable(self, filename_without_extension: str) -> str: + ... + + +geode_objects: dict[GeodeType, type[GeodeObject]] = {"BRep": GeodeBRep} + + mesh = "mesh" model = "model" @@ -19,552 +101,553 @@ polyhedrons = "polyhedrons" -def geode_objects_dict(): - return { - "BRep": { - "class": og.BRep, - "input_factory": og.BRepInputFactory, - "output_factory": og.BRepOutputFactory, - "additional_files": og.brep_additional_files, - "is_loadable": og.is_brep_loadable, - "object_priority": og.brep_object_priority, - "load": og.load_brep, - "is_saveable": og.is_brep_saveable, - "save": og.save_brep, - "builder": og.BRepBuilder, - "crs": { - "assign": og_gs.assign_brep_geographic_coordinate_system_info, - "convert": og_gs.convert_brep_coordinate_reference_system, - "create": og.create_brep_coordinate_system, - }, - "object_type": model, - "is_3D": True, - "is_viewable": True, - "save_viewable": g_v.save_viewable_brep, - "save_light_viewable": g_v.save_light_viewable_brep, - "inspector": og_inspector.inspect_brep, - }, - "CrossSection": { - "parent": "Section", - "class": og_gs.CrossSection, - "input_factory": og_gs.CrossSectionInputFactory, - "output_factory": og_gs.CrossSectionOutputFactory, - "additional_files": og_gs.cross_section_additional_files, - "is_loadable": og_gs.is_cross_section_loadable, - "object_priority": og_gs.cross_section_object_priority, - "load": og_gs.load_cross_section, - "is_saveable": og_gs.is_cross_section_saveable, - "save": og_gs.save_cross_section, - "builder": og_gs.CrossSectionBuilder, - "crs": { - "assign": og_gs.assign_section_geographic_coordinate_system_info, - "convert": og_gs.convert_section_coordinate_reference_system, - "create": og.create_section_coordinate_system, - }, - "object_type": model, - "is_3D": False, - "is_viewable": True, - "save_viewable": g_v.save_viewable_cross_section, - "save_light_viewable": g_v.save_light_viewable_cross_section, - "inspector": og_inspector.inspect_section, - }, - "EdgedCurve2D": { - "class": og.EdgedCurve2D, - "input_factory": og.EdgedCurveInputFactory2D, - "output_factory": og.EdgedCurveOutputFactory2D, - "additional_files": og.edged_curve_additional_files2D, - "is_loadable": og.is_edged_curve_loadable2D, - "object_priority": og.edged_curve_object_priority2D, - "load": og.load_edged_curve2D, - "is_saveable": og.is_edged_curve_saveable2D, - "save": og.save_edged_curve2D, - "builder": og.EdgedCurveBuilder2D.create, - "crs": { - "assign": og_gs.assign_edged_curve_geographic_coordinate_system_info2D, - "convert": og_gs.convert_edged_curve_coordinate_reference_system2D, - "create": og.create_edged_curve_coordinate_system2D, - }, - "object_type": mesh, - "elements": [points, edges], - "is_3D": False, - "is_viewable": True, - "save_viewable": g_v.save_viewable_edged_curve2D, - "save_light_viewable": g_v.save_light_viewable_edged_curve2D, - "inspector": og_inspector.inspect_edged_curve2D, - }, - "EdgedCurve3D": { - "class": og.EdgedCurve3D, - "input_factory": og.EdgedCurveInputFactory3D, - "output_factory": og.EdgedCurveOutputFactory3D, - "additional_files": og.edged_curve_additional_files3D, - "is_loadable": og.is_edged_curve_loadable3D, - "object_priority": og.edged_curve_object_priority3D, - "load": og.load_edged_curve3D, - "is_saveable": og.is_edged_curve_saveable3D, - "save": og.save_edged_curve3D, - "builder": og.EdgedCurveBuilder3D.create, - "crs": { - "assign": og_gs.assign_edged_curve_geographic_coordinate_system_info3D, - "convert": og_gs.convert_edged_curve_coordinate_reference_system3D, - "create": og.create_edged_curve_coordinate_system3D, - }, - "object_type": mesh, - "elements": [points, edges], - "is_3D": True, - "is_viewable": True, - "save_viewable": g_v.save_viewable_edged_curve3D, - "save_light_viewable": g_v.save_light_viewable_edged_curve3D, - "inspector": og_inspector.inspect_edged_curve3D, - }, - "Graph": { - "class": og.Graph, - "input_factory": og.GraphInputFactory, - "output_factory": og.GraphOutputFactory, - "additional_files": og.graph_additional_files, - "is_loadable": og.is_graph_loadable, - "object_priority": og.graph_object_priority, - "load": og.load_graph, - "is_saveable": og.is_graph_saveable, - "save": og.save_graph, - "builder": og.GraphBuilder.create, - "object_type": mesh, - "is_3D": False, - "is_viewable": False, - }, - "HybridSolid3D": { - "class": og.HybridSolid3D, - "input_factory": og.HybridSolidInputFactory3D, - "output_factory": og.HybridSolidOutputFactory3D, - "additional_files": og.hybrid_solid_additional_files3D, - "is_loadable": og.is_hybrid_solid_loadable3D, - "object_priority": og.hybrid_solid_object_priority3D, - "load": og.load_hybrid_solid3D, - "is_saveable": og.is_hybrid_solid_saveable3D, - "save": og.save_hybrid_solid3D, - "builder": og.HybridSolidBuilder3D.create, - "crs": { - "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, - "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, - "create": og.create_solid_mesh_coordinate_system3D, - }, - "object_type": mesh, - "elements": [points, polyhedrons], - "is_3D": True, - "is_viewable": True, - "save_viewable": g_v.save_viewable_hybrid_solid3D, - "save_light_viewable": g_v.save_light_viewable_hybrid_solid3D, - "inspector": og_inspector.inspect_solid3D, - }, - "ImplicitCrossSection": { - "parent": "CrossSection", - "class": og_gs.ImplicitCrossSection, - "input_factory": og_gs.ImplicitCrossSectionInputFactory, - "output_factory": og_gs.ImplicitCrossSectionOutputFactory, - "additional_files": og_gs.implicit_cross_section_additional_files, - "is_loadable": og_gs.is_implicit_cross_section_loadable, - "object_priority": og_gs.implicit_cross_section_object_priority, - "load": og_gs.load_implicit_cross_section, - "is_saveable": og_gs.is_implicit_cross_section_saveable, - "save": og_gs.save_implicit_cross_section, - "builder": og_gs.ImplicitCrossSectionBuilder, - "crs": { - "assign": og_gs.assign_section_geographic_coordinate_system_info, - "convert": og_gs.convert_section_coordinate_reference_system, - "create": og.create_section_coordinate_system, - }, - "object_type": model, - "is_3D": False, - "is_viewable": True, - "save_viewable": g_v.save_viewable_implicit_cross_section, - "save_light_viewable": g_v.save_light_viewable_implicit_cross_section, - "inspector": og_inspector.inspect_section, - }, - "ImplicitStructuralModel": { - "parent": "StructuralModel", - "class": og_gs.ImplicitStructuralModel, - "input_factory": og_gs.ImplicitStructuralModelInputFactory, - "output_factory": og_gs.ImplicitStructuralModelOutputFactory, - "additional_files": og_gs.implicit_structural_model_additional_files, - "is_loadable": og_gs.is_implicit_structural_model_loadable, - "object_priority": og_gs.implicit_structural_model_object_priority, - "load": og_gs.load_implicit_structural_model, - "is_saveable": og_gs.is_implicit_structural_model_saveable, - "save": og_gs.save_implicit_structural_model, - "builder": og_gs.ImplicitStructuralModelBuilder, - "crs": { - "assign": og_gs.assign_brep_geographic_coordinate_system_info, - "convert": og_gs.convert_brep_coordinate_reference_system, - "create": og.create_brep_coordinate_system, - }, - "object_type": model, - "is_3D": True, - "is_viewable": True, - "save_viewable": g_v.save_viewable_implicit_structural_model, - "save_light_viewable": g_v.save_light_viewable_implicit_structural_model, - "inspector": og_inspector.inspect_brep, - }, - "LightRegularGrid2D": { - "class": og.LightRegularGrid2D, - "input_factory": og.LightRegularGridInputFactory2D, - "output_factory": og.LightRegularGridOutputFactory2D, - "additional_files": og.light_regular_grid_additional_files2D, - "is_loadable": og.is_light_regular_grid_loadable2D, - "object_priority": og.light_regular_grid_object_priority2D, - "load": og.load_light_regular_grid2D, - "is_saveable": og.is_light_regular_grid_saveable2D, - "save": og.save_light_regular_grid2D, - "object_type": mesh, - "elements": [points, polygons], - "is_3D": False, - "is_viewable": True, - "save_viewable": g_v.save_viewable_light_regular_grid2D, - "save_light_viewable": g_v.save_light_viewable_light_regular_grid2D, - }, - "LightRegularGrid3D": { - "class": og.LightRegularGrid3D, - "input_factory": og.LightRegularGridInputFactory3D, - "output_factory": og.LightRegularGridOutputFactory3D, - "additional_files": og.light_regular_grid_additional_files3D, - "is_loadable": og.is_light_regular_grid_loadable3D, - "object_priority": og.light_regular_grid_object_priority3D, - "load": og.load_light_regular_grid3D, - "is_saveable": og.is_light_regular_grid_saveable3D, - "save": og.save_light_regular_grid3D, - "object_type": mesh, - "elements": [points, polyhedrons], - "is_3D": True, - "is_viewable": True, - "save_viewable": g_v.save_viewable_light_regular_grid3D, - "save_light_viewable": g_v.save_light_viewable_light_regular_grid3D, - }, - "PointSet2D": { - "class": og.PointSet2D, - "input_factory": og.PointSetInputFactory2D, - "output_factory": og.PointSetOutputFactory2D, - "additional_files": og.point_set_additional_files2D, - "is_loadable": og.is_point_set_loadable2D, - "object_priority": og.point_set_object_priority2D, - "load": og.load_point_set2D, - "is_saveable": og.is_point_set_saveable2D, - "save": og.save_point_set2D, - "builder": og.PointSetBuilder2D.create, - "crs": { - "assign": og_gs.assign_point_set_geographic_coordinate_system_info2D, - "convert": og_gs.convert_point_set_coordinate_reference_system2D, - "create": og.create_point_set_coordinate_system2D, - }, - "object_type": mesh, - "elements": [points], - "is_3D": False, - "is_viewable": True, - "save_viewable": g_v.save_viewable_point_set2D, - "save_light_viewable": g_v.save_light_viewable_point_set2D, - "inspector": og_inspector.inspect_point_set2D, - }, - "PointSet3D": { - "class": og.PointSet3D, - "input_factory": og.PointSetInputFactory3D, - "output_factory": og.PointSetOutputFactory3D, - "additional_files": og.point_set_additional_files3D, - "is_loadable": og.is_point_set_loadable3D, - "object_priority": og.point_set_object_priority3D, - "load": og.load_point_set3D, - "is_saveable": og.is_point_set_saveable3D, - "save": og.save_point_set3D, - "builder": og.PointSetBuilder3D.create, - "crs": { - "assign": og_gs.assign_point_set_geographic_coordinate_system_info3D, - "convert": og_gs.convert_point_set_coordinate_reference_system3D, - "create": og.create_point_set_coordinate_system3D, - }, - "object_type": mesh, - "elements": [points], - "is_3D": True, - "is_viewable": True, - "save_viewable": g_v.save_viewable_point_set3D, - "save_light_viewable": g_v.save_light_viewable_point_set3D, - "inspector": og_inspector.inspect_point_set3D, - }, - "PolygonalSurface2D": { - "class": og.PolygonalSurface2D, - "input_factory": og.PolygonalSurfaceInputFactory2D, - "output_factory": og.PolygonalSurfaceOutputFactory2D, - "additional_files": og.polygonal_surface_additional_files2D, - "is_loadable": og.is_polygonal_surface_loadable2D, - "object_priority": og.polygonal_surface_object_priority2D, - "load": og.load_polygonal_surface2D, - "is_saveable": og.is_polygonal_surface_saveable2D, - "save": og.save_polygonal_surface2D, - "builder": og.PolygonalSurfaceBuilder2D.create, - "crs": { - "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, - "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, - "create": og.create_surface_mesh_coordinate_system2D, - }, - "object_type": mesh, - "elements": [points, polygons], - "is_3D": False, - "is_viewable": True, - "save_viewable": g_v.save_viewable_polygonal_surface2D, - "save_light_viewable": g_v.save_light_viewable_polygonal_surface2D, - "inspector": og_inspector.inspect_surface2D, - }, - "PolygonalSurface3D": { - "class": og.PolygonalSurface3D, - "input_factory": og.PolygonalSurfaceInputFactory3D, - "output_factory": og.PolygonalSurfaceOutputFactory3D, - "additional_files": og.polygonal_surface_additional_files3D, - "is_loadable": og.is_polygonal_surface_loadable3D, - "object_priority": og.polygonal_surface_object_priority3D, - "load": og.load_polygonal_surface3D, - "is_saveable": og.is_polygonal_surface_saveable3D, - "save": og.save_polygonal_surface3D, - "builder": og.PolygonalSurfaceBuilder3D.create, - "crs": { - "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info3D, - "convert": og_gs.convert_surface_mesh_coordinate_reference_system3D, - "create": og.create_surface_mesh_coordinate_system3D, - }, - "object_type": mesh, - "elements": [points, polygons], - "is_3D": True, - "is_viewable": True, - "save_viewable": g_v.save_viewable_polygonal_surface3D, - "save_light_viewable": g_v.save_light_viewable_polygonal_surface3D, - "inspector": og_inspector.inspect_surface3D, - }, - "PolyhedralSolid3D": { - "class": og.PolyhedralSolid3D, - "input_factory": og.PolyhedralSolidInputFactory3D, - "output_factory": og.PolyhedralSolidOutputFactory3D, - "additional_files": og.polyhedral_solid_additional_files3D, - "is_loadable": og.is_polyhedral_solid_loadable3D, - "object_priority": og.polyhedral_solid_object_priority3D, - "load": og.load_polyhedral_solid3D, - "is_saveable": og.is_polyhedral_solid_saveable3D, - "save": og.save_polyhedral_solid3D, - "builder": og.PolyhedralSolidBuilder3D.create, - "crs": { - "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, - "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, - "create": og.create_solid_mesh_coordinate_system3D, - }, - "object_type": mesh, - "elements": [points, polyhedrons], - "is_3D": True, - "is_viewable": True, - "save_viewable": g_v.save_viewable_polyhedral_solid3D, - "save_light_viewable": g_v.save_light_viewable_polyhedral_solid3D, - "inspector": og_inspector.inspect_solid3D, - }, - "RasterImage2D": { - "class": og.RasterImage2D, - "input_factory": og.RasterImageInputFactory2D, - "output_factory": og.RasterImageOutputFactory2D, - "additional_files": og.raster_image_additional_files2D, - "is_loadable": og.is_raster_image_loadable2D, - "object_priority": og.raster_image_object_priority2D, - "load": og.load_raster_image2D, - "is_saveable": og.is_raster_image_saveable2D, - "save": og.save_raster_image2D, - "object_type": mesh, - "is_3D": False, - "is_viewable": True, - "save_viewable": g_v.save_viewable_raster_image2D, - }, - "RasterImage3D": { - "class": og.RasterImage3D, - "input_factory": og.RasterImageInputFactory3D, - "output_factory": og.RasterImageOutputFactory3D, - "additional_files": og.raster_image_additional_files3D, - "is_loadable": og.is_raster_image_loadable3D, - "object_priority": og.raster_image_object_priority3D, - "load": og.load_raster_image3D, - "is_saveable": og.is_raster_image_saveable3D, - "save": og.save_raster_image3D, - "object_type": mesh, - "is_3D": False, - "is_viewable": True, - "save_viewable": g_v.save_viewable_raster_image3D, - }, - "RegularGrid2D": { - "class": og.RegularGrid2D, - "input_factory": og.RegularGridInputFactory2D, - "output_factory": og.RegularGridOutputFactory2D, - "additional_files": og.regular_grid_additional_files2D, - "is_loadable": og.is_regular_grid_loadable2D, - "object_priority": og.regular_grid_object_priority2D, - "load": og.load_regular_grid2D, - "is_saveable": og.is_regular_grid_saveable2D, - "save": og.save_regular_grid2D, - "builder": og.RegularGridBuilder2D.create, - "crs": { - "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, - "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, - "create": og.create_surface_mesh_coordinate_system2D, - }, - "object_type": mesh, - "elements": [points, polygons], - "is_3D": False, - "is_viewable": True, - "save_viewable": g_v.save_viewable_regular_grid2D, - "save_light_viewable": g_v.save_light_viewable_regular_grid2D, - }, - "RegularGrid3D": { - "class": og.RegularGrid3D, - "input_factory": og.RegularGridInputFactory3D, - "output_factory": og.RegularGridOutputFactory3D, - "additional_files": og.regular_grid_additional_files3D, - "is_loadable": og.is_regular_grid_loadable3D, - "object_priority": og.regular_grid_object_priority3D, - "load": og.load_regular_grid3D, - "is_saveable": og.is_regular_grid_saveable3D, - "save": og.save_regular_grid3D, - "builder": og.RegularGridBuilder3D.create, - "crs": { - "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, - "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, - "create": og.create_surface_mesh_coordinate_system3D, - }, - "object_type": mesh, - "elements": [points, polyhedrons], - "is_3D": True, - "is_viewable": True, - "save_viewable": g_v.save_viewable_regular_grid3D, - "save_light_viewable": g_v.save_light_viewable_regular_grid3D, - }, - "Section": { - "class": og.Section, - "input_factory": og.SectionInputFactory, - "output_factory": og.SectionOutputFactory, - "additional_files": og.section_additional_files, - "is_loadable": og.is_section_loadable, - "object_priority": og.section_object_priority, - "load": og.load_section, - "is_saveable": og.is_section_saveable, - "save": og.save_section, - "builder": og.SectionBuilder, - "crs": { - "assign": og_gs.assign_section_geographic_coordinate_system_info, - "convert": og_gs.convert_section_coordinate_reference_system, - "create": og.create_section_coordinate_system, - }, - "object_type": model, - "is_3D": False, - "is_viewable": True, - "save_viewable": g_v.save_viewable_section, - "save_light_viewable": g_v.save_light_viewable_section, - "inspector": og_inspector.inspect_section, - }, - "StructuralModel": { - "parent": "BRep", - "class": og_gs.StructuralModel, - "input_factory": og_gs.StructuralModelInputFactory, - "output_factory": og_gs.StructuralModelOutputFactory, - "additional_files": og_gs.structural_model_additional_files, - "is_loadable": og_gs.is_structural_model_loadable, - "object_priority": og_gs.structural_model_object_priority, - "load": og_gs.load_structural_model, - "is_saveable": og_gs.is_structural_model_saveable, - "save": og_gs.save_structural_model, - "builder": og_gs.StructuralModelBuilder, - "crs": { - "assign": og_gs.assign_brep_geographic_coordinate_system_info, - "convert": og_gs.convert_brep_coordinate_reference_system, - "create": og.create_brep_coordinate_system, - }, - "object_type": model, - "is_3D": True, - "is_viewable": True, - "save_viewable": g_v.save_viewable_structural_model, - "save_light_viewable": g_v.save_light_viewable_structural_model, - "inspector": og_inspector.inspect_brep, - }, - "TetrahedralSolid3D": { - "class": og.TetrahedralSolid3D, - "input_factory": og.TetrahedralSolidInputFactory3D, - "output_factory": og.TetrahedralSolidOutputFactory3D, - "additional_files": og.tetrahedral_solid_additional_files3D, - "is_loadable": og.is_tetrahedral_solid_loadable3D, - "object_priority": og.tetrahedral_solid_object_priority3D, - "load": og.load_tetrahedral_solid3D, - "is_saveable": og.is_tetrahedral_solid_saveable3D, - "save": og.save_tetrahedral_solid3D, - "builder": og.TetrahedralSolidBuilder3D.create, - "crs": { - "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, - "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, - "create": og.create_solid_mesh_coordinate_system3D, - }, - "object_type": mesh, - "elements": [points, polyhedrons], - "is_3D": True, - "is_viewable": True, - "save_viewable": g_v.save_viewable_tetrahedral_solid3D, - "save_light_viewable": g_v.save_light_viewable_tetrahedral_solid3D, - "inspector": og_inspector.inspect_solid3D, - }, - "TriangulatedSurface2D": { - "class": og.TriangulatedSurface2D, - "input_factory": og.TriangulatedSurfaceInputFactory2D, - "output_factory": og.TriangulatedSurfaceOutputFactory2D, - "additional_files": og.triangulated_surface_additional_files2D, - "is_loadable": og.is_triangulated_surface_loadable2D, - "object_priority": og.triangulated_surface_object_priority2D, - "load": og.load_triangulated_surface2D, - "is_saveable": og.is_triangulated_surface_saveable2D, - "save": og.save_triangulated_surface2D, - "builder": og.TriangulatedSurfaceBuilder2D.create, - "crs": { - "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, - "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, - "create": og.create_surface_mesh_coordinate_system2D, - }, - "object_type": mesh, - "elements": [points, polygons], - "is_3D": False, - "is_viewable": True, - "save_viewable": g_v.save_viewable_triangulated_surface2D, - "save_light_viewable": g_v.save_light_viewable_triangulated_surface2D, - "inspector": og_inspector.inspect_surface2D, - }, - "TriangulatedSurface3D": { - "class": og.TriangulatedSurface3D, - "input_factory": og.TriangulatedSurfaceInputFactory3D, - "output_factory": og.TriangulatedSurfaceOutputFactory3D, - "additional_files": og.triangulated_surface_additional_files3D, - "is_loadable": og.is_triangulated_surface_loadable3D, - "object_priority": og.triangulated_surface_object_priority3D, - "load": og.load_triangulated_surface3D, - "is_saveable": og.is_triangulated_surface_saveable3D, - "save": og.save_triangulated_surface3D, - "builder": og.TriangulatedSurfaceBuilder3D.create, - "crs": { - "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info3D, - "convert": og_gs.convert_surface_mesh_coordinate_reference_system3D, - "create": og.create_surface_mesh_coordinate_system3D, - }, - "object_type": mesh, - "elements": [points, polygons], - "is_3D": True, - "is_viewable": True, - "save_viewable": g_v.save_viewable_triangulated_surface3D, - "save_light_viewable": g_v.save_light_viewable_triangulated_surface3D, - "inspector": og_inspector.inspect_surface3D, - }, - "VertexSet": { - "class": og.VertexSet, - "input_factory": og.VertexSetInputFactory, - "output_factory": og.VertexSetOutputFactory, - "additional_files": og.vertex_set_additional_files, - "is_loadable": og.is_vertex_set_loadable, - "object_priority": og.vertex_set_object_priority, - "load": og.load_vertex_set, - "is_saveable": og.is_vertex_set_saveable, - "save": og.save_vertex_set, - "builder": og.VertexSetBuilder.create, - "object_type": mesh, - "is_3D": False, - "is_viewable": False, - }, - } + +# def geode_objects_dict(): +# return { +# "BRep": { +# "class": og.BRep, +# "input_factory": og.BRepInputFactory, +# "output_factory": og.BRepOutputFactory, +# "additional_files": og.brep_additional_files, +# "is_loadable": og.is_brep_loadable, +# "object_priority": og.brep_object_priority, +# "load": og.load_brep, +# "is_saveable": og.is_brep_saveable, +# "save": og.save_brep, +# "builder": og.BRepBuilder, +# "crs": { +# "assign": og_gs.assign_brep_geographic_coordinate_system_info, +# "convert": og_gs.convert_brep_coordinate_reference_system, +# "create": og.create_brep_coordinate_system, +# }, +# "object_type": model, +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_brep, +# "save_light_viewable": g_v.save_light_viewable_brep, +# "inspector": og_inspector.inspect_brep, +# }, +# "CrossSection": { +# "parent": "Section", +# "class": og_gs.CrossSection, +# "input_factory": og_gs.CrossSectionInputFactory, +# "output_factory": og_gs.CrossSectionOutputFactory, +# "additional_files": og_gs.cross_section_additional_files, +# "is_loadable": og_gs.is_cross_section_loadable, +# "object_priority": og_gs.cross_section_object_priority, +# "load": og_gs.load_cross_section, +# "is_saveable": og_gs.is_cross_section_saveable, +# "save": og_gs.save_cross_section, +# "builder": og_gs.CrossSectionBuilder, +# "crs": { +# "assign": og_gs.assign_section_geographic_coordinate_system_info, +# "convert": og_gs.convert_section_coordinate_reference_system, +# "create": og.create_section_coordinate_system, +# }, +# "object_type": model, +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_cross_section, +# "save_light_viewable": g_v.save_light_viewable_cross_section, +# "inspector": og_inspector.inspect_section, +# }, +# "EdgedCurve2D": { +# "class": og.EdgedCurve2D, +# "input_factory": og.EdgedCurveInputFactory2D, +# "output_factory": og.EdgedCurveOutputFactory2D, +# "additional_files": og.edged_curve_additional_files2D, +# "is_loadable": og.is_edged_curve_loadable2D, +# "object_priority": og.edged_curve_object_priority2D, +# "load": og.load_edged_curve2D, +# "is_saveable": og.is_edged_curve_saveable2D, +# "save": og.save_edged_curve2D, +# "builder": og.EdgedCurveBuilder2D.create, +# "crs": { +# "assign": og_gs.assign_edged_curve_geographic_coordinate_system_info2D, +# "convert": og_gs.convert_edged_curve_coordinate_reference_system2D, +# "create": og.create_edged_curve_coordinate_system2D, +# }, +# "object_type": mesh, +# "elements": [points, edges], +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_edged_curve2D, +# "save_light_viewable": g_v.save_light_viewable_edged_curve2D, +# "inspector": og_inspector.inspect_edged_curve2D, +# }, +# "EdgedCurve3D": { +# "class": og.EdgedCurve3D, +# "input_factory": og.EdgedCurveInputFactory3D, +# "output_factory": og.EdgedCurveOutputFactory3D, +# "additional_files": og.edged_curve_additional_files3D, +# "is_loadable": og.is_edged_curve_loadable3D, +# "object_priority": og.edged_curve_object_priority3D, +# "load": og.load_edged_curve3D, +# "is_saveable": og.is_edged_curve_saveable3D, +# "save": og.save_edged_curve3D, +# "builder": og.EdgedCurveBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_edged_curve_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_edged_curve_coordinate_reference_system3D, +# "create": og.create_edged_curve_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, edges], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_edged_curve3D, +# "save_light_viewable": g_v.save_light_viewable_edged_curve3D, +# "inspector": og_inspector.inspect_edged_curve3D, +# }, +# "Graph": { +# "class": og.Graph, +# "input_factory": og.GraphInputFactory, +# "output_factory": og.GraphOutputFactory, +# "additional_files": og.graph_additional_files, +# "is_loadable": og.is_graph_loadable, +# "object_priority": og.graph_object_priority, +# "load": og.load_graph, +# "is_saveable": og.is_graph_saveable, +# "save": og.save_graph, +# "builder": og.GraphBuilder.create, +# "object_type": mesh, +# "is_3D": False, +# "is_viewable": False, +# }, +# "HybridSolid3D": { +# "class": og.HybridSolid3D, +# "input_factory": og.HybridSolidInputFactory3D, +# "output_factory": og.HybridSolidOutputFactory3D, +# "additional_files": og.hybrid_solid_additional_files3D, +# "is_loadable": og.is_hybrid_solid_loadable3D, +# "object_priority": og.hybrid_solid_object_priority3D, +# "load": og.load_hybrid_solid3D, +# "is_saveable": og.is_hybrid_solid_saveable3D, +# "save": og.save_hybrid_solid3D, +# "builder": og.HybridSolidBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, +# "create": og.create_solid_mesh_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, polyhedrons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_hybrid_solid3D, +# "save_light_viewable": g_v.save_light_viewable_hybrid_solid3D, +# "inspector": og_inspector.inspect_solid3D, +# }, +# "ImplicitCrossSection": { +# "parent": "CrossSection", +# "class": og_gs.ImplicitCrossSection, +# "input_factory": og_gs.ImplicitCrossSectionInputFactory, +# "output_factory": og_gs.ImplicitCrossSectionOutputFactory, +# "additional_files": og_gs.implicit_cross_section_additional_files, +# "is_loadable": og_gs.is_implicit_cross_section_loadable, +# "object_priority": og_gs.implicit_cross_section_object_priority, +# "load": og_gs.load_implicit_cross_section, +# "is_saveable": og_gs.is_implicit_cross_section_saveable, +# "save": og_gs.save_implicit_cross_section, +# "builder": og_gs.ImplicitCrossSectionBuilder, +# "crs": { +# "assign": og_gs.assign_section_geographic_coordinate_system_info, +# "convert": og_gs.convert_section_coordinate_reference_system, +# "create": og.create_section_coordinate_system, +# }, +# "object_type": model, +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_implicit_cross_section, +# "save_light_viewable": g_v.save_light_viewable_implicit_cross_section, +# "inspector": og_inspector.inspect_section, +# }, +# "ImplicitStructuralModel": { +# "parent": "StructuralModel", +# "class": og_gs.ImplicitStructuralModel, +# "input_factory": og_gs.ImplicitStructuralModelInputFactory, +# "output_factory": og_gs.ImplicitStructuralModelOutputFactory, +# "additional_files": og_gs.implicit_structural_model_additional_files, +# "is_loadable": og_gs.is_implicit_structural_model_loadable, +# "object_priority": og_gs.implicit_structural_model_object_priority, +# "load": og_gs.load_implicit_structural_model, +# "is_saveable": og_gs.is_implicit_structural_model_saveable, +# "save": og_gs.save_implicit_structural_model, +# "builder": og_gs.ImplicitStructuralModelBuilder, +# "crs": { +# "assign": og_gs.assign_brep_geographic_coordinate_system_info, +# "convert": og_gs.convert_brep_coordinate_reference_system, +# "create": og.create_brep_coordinate_system, +# }, +# "object_type": model, +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_implicit_structural_model, +# "save_light_viewable": g_v.save_light_viewable_implicit_structural_model, +# "inspector": og_inspector.inspect_brep, +# }, +# "LightRegularGrid2D": { +# "class": og.LightRegularGrid2D, +# "input_factory": og.LightRegularGridInputFactory2D, +# "output_factory": og.LightRegularGridOutputFactory2D, +# "additional_files": og.light_regular_grid_additional_files2D, +# "is_loadable": og.is_light_regular_grid_loadable2D, +# "object_priority": og.light_regular_grid_object_priority2D, +# "load": og.load_light_regular_grid2D, +# "is_saveable": og.is_light_regular_grid_saveable2D, +# "save": og.save_light_regular_grid2D, +# "object_type": mesh, +# "elements": [points, polygons], +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_light_regular_grid2D, +# "save_light_viewable": g_v.save_light_viewable_light_regular_grid2D, +# }, +# "LightRegularGrid3D": { +# "class": og.LightRegularGrid3D, +# "input_factory": og.LightRegularGridInputFactory3D, +# "output_factory": og.LightRegularGridOutputFactory3D, +# "additional_files": og.light_regular_grid_additional_files3D, +# "is_loadable": og.is_light_regular_grid_loadable3D, +# "object_priority": og.light_regular_grid_object_priority3D, +# "load": og.load_light_regular_grid3D, +# "is_saveable": og.is_light_regular_grid_saveable3D, +# "save": og.save_light_regular_grid3D, +# "object_type": mesh, +# "elements": [points, polyhedrons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_light_regular_grid3D, +# "save_light_viewable": g_v.save_light_viewable_light_regular_grid3D, +# }, +# "PointSet2D": { +# "class": og.PointSet2D, +# "input_factory": og.PointSetInputFactory2D, +# "output_factory": og.PointSetOutputFactory2D, +# "additional_files": og.point_set_additional_files2D, +# "is_loadable": og.is_point_set_loadable2D, +# "object_priority": og.point_set_object_priority2D, +# "load": og.load_point_set2D, +# "is_saveable": og.is_point_set_saveable2D, +# "save": og.save_point_set2D, +# "builder": og.PointSetBuilder2D.create, +# "crs": { +# "assign": og_gs.assign_point_set_geographic_coordinate_system_info2D, +# "convert": og_gs.convert_point_set_coordinate_reference_system2D, +# "create": og.create_point_set_coordinate_system2D, +# }, +# "object_type": mesh, +# "elements": [points], +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_point_set2D, +# "save_light_viewable": g_v.save_light_viewable_point_set2D, +# "inspector": og_inspector.inspect_point_set2D, +# }, +# "PointSet3D": { +# "class": og.PointSet3D, +# "input_factory": og.PointSetInputFactory3D, +# "output_factory": og.PointSetOutputFactory3D, +# "additional_files": og.point_set_additional_files3D, +# "is_loadable": og.is_point_set_loadable3D, +# "object_priority": og.point_set_object_priority3D, +# "load": og.load_point_set3D, +# "is_saveable": og.is_point_set_saveable3D, +# "save": og.save_point_set3D, +# "builder": og.PointSetBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_point_set_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_point_set_coordinate_reference_system3D, +# "create": og.create_point_set_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_point_set3D, +# "save_light_viewable": g_v.save_light_viewable_point_set3D, +# "inspector": og_inspector.inspect_point_set3D, +# }, +# "PolygonalSurface2D": { +# "class": og.PolygonalSurface2D, +# "input_factory": og.PolygonalSurfaceInputFactory2D, +# "output_factory": og.PolygonalSurfaceOutputFactory2D, +# "additional_files": og.polygonal_surface_additional_files2D, +# "is_loadable": og.is_polygonal_surface_loadable2D, +# "object_priority": og.polygonal_surface_object_priority2D, +# "load": og.load_polygonal_surface2D, +# "is_saveable": og.is_polygonal_surface_saveable2D, +# "save": og.save_polygonal_surface2D, +# "builder": og.PolygonalSurfaceBuilder2D.create, +# "crs": { +# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, +# "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, +# "create": og.create_surface_mesh_coordinate_system2D, +# }, +# "object_type": mesh, +# "elements": [points, polygons], +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_polygonal_surface2D, +# "save_light_viewable": g_v.save_light_viewable_polygonal_surface2D, +# "inspector": og_inspector.inspect_surface2D, +# }, +# "PolygonalSurface3D": { +# "class": og.PolygonalSurface3D, +# "input_factory": og.PolygonalSurfaceInputFactory3D, +# "output_factory": og.PolygonalSurfaceOutputFactory3D, +# "additional_files": og.polygonal_surface_additional_files3D, +# "is_loadable": og.is_polygonal_surface_loadable3D, +# "object_priority": og.polygonal_surface_object_priority3D, +# "load": og.load_polygonal_surface3D, +# "is_saveable": og.is_polygonal_surface_saveable3D, +# "save": og.save_polygonal_surface3D, +# "builder": og.PolygonalSurfaceBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_surface_mesh_coordinate_reference_system3D, +# "create": og.create_surface_mesh_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, polygons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_polygonal_surface3D, +# "save_light_viewable": g_v.save_light_viewable_polygonal_surface3D, +# "inspector": og_inspector.inspect_surface3D, +# }, +# "PolyhedralSolid3D": { +# "class": og.PolyhedralSolid3D, +# "input_factory": og.PolyhedralSolidInputFactory3D, +# "output_factory": og.PolyhedralSolidOutputFactory3D, +# "additional_files": og.polyhedral_solid_additional_files3D, +# "is_loadable": og.is_polyhedral_solid_loadable3D, +# "object_priority": og.polyhedral_solid_object_priority3D, +# "load": og.load_polyhedral_solid3D, +# "is_saveable": og.is_polyhedral_solid_saveable3D, +# "save": og.save_polyhedral_solid3D, +# "builder": og.PolyhedralSolidBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, +# "create": og.create_solid_mesh_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, polyhedrons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_polyhedral_solid3D, +# "save_light_viewable": g_v.save_light_viewable_polyhedral_solid3D, +# "inspector": og_inspector.inspect_solid3D, +# }, +# "RasterImage2D": { +# "class": og.RasterImage2D, +# "input_factory": og.RasterImageInputFactory2D, +# "output_factory": og.RasterImageOutputFactory2D, +# "additional_files": og.raster_image_additional_files2D, +# "is_loadable": og.is_raster_image_loadable2D, +# "object_priority": og.raster_image_object_priority2D, +# "load": og.load_raster_image2D, +# "is_saveable": og.is_raster_image_saveable2D, +# "save": og.save_raster_image2D, +# "object_type": mesh, +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_raster_image2D, +# }, +# "RasterImage3D": { +# "class": og.RasterImage3D, +# "input_factory": og.RasterImageInputFactory3D, +# "output_factory": og.RasterImageOutputFactory3D, +# "additional_files": og.raster_image_additional_files3D, +# "is_loadable": og.is_raster_image_loadable3D, +# "object_priority": og.raster_image_object_priority3D, +# "load": og.load_raster_image3D, +# "is_saveable": og.is_raster_image_saveable3D, +# "save": og.save_raster_image3D, +# "object_type": mesh, +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_raster_image3D, +# }, +# "RegularGrid2D": { +# "class": og.RegularGrid2D, +# "input_factory": og.RegularGridInputFactory2D, +# "output_factory": og.RegularGridOutputFactory2D, +# "additional_files": og.regular_grid_additional_files2D, +# "is_loadable": og.is_regular_grid_loadable2D, +# "object_priority": og.regular_grid_object_priority2D, +# "load": og.load_regular_grid2D, +# "is_saveable": og.is_regular_grid_saveable2D, +# "save": og.save_regular_grid2D, +# "builder": og.RegularGridBuilder2D.create, +# "crs": { +# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, +# "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, +# "create": og.create_surface_mesh_coordinate_system2D, +# }, +# "object_type": mesh, +# "elements": [points, polygons], +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_regular_grid2D, +# "save_light_viewable": g_v.save_light_viewable_regular_grid2D, +# }, +# "RegularGrid3D": { +# "class": og.RegularGrid3D, +# "input_factory": og.RegularGridInputFactory3D, +# "output_factory": og.RegularGridOutputFactory3D, +# "additional_files": og.regular_grid_additional_files3D, +# "is_loadable": og.is_regular_grid_loadable3D, +# "object_priority": og.regular_grid_object_priority3D, +# "load": og.load_regular_grid3D, +# "is_saveable": og.is_regular_grid_saveable3D, +# "save": og.save_regular_grid3D, +# "builder": og.RegularGridBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, +# "create": og.create_surface_mesh_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, polyhedrons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_regular_grid3D, +# "save_light_viewable": g_v.save_light_viewable_regular_grid3D, +# }, +# "Section": { +# "class": og.Section, +# "input_factory": og.SectionInputFactory, +# "output_factory": og.SectionOutputFactory, +# "additional_files": og.section_additional_files, +# "is_loadable": og.is_section_loadable, +# "object_priority": og.section_object_priority, +# "load": og.load_section, +# "is_saveable": og.is_section_saveable, +# "save": og.save_section, +# "builder": og.SectionBuilder, +# "crs": { +# "assign": og_gs.assign_section_geographic_coordinate_system_info, +# "convert": og_gs.convert_section_coordinate_reference_system, +# "create": og.create_section_coordinate_system, +# }, +# "object_type": model, +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_section, +# "save_light_viewable": g_v.save_light_viewable_section, +# "inspector": og_inspector.inspect_section, +# }, +# "StructuralModel": { +# "parent": "BRep", +# "class": og_gs.StructuralModel, +# "input_factory": og_gs.StructuralModelInputFactory, +# "output_factory": og_gs.StructuralModelOutputFactory, +# "additional_files": og_gs.structural_model_additional_files, +# "is_loadable": og_gs.is_structural_model_loadable, +# "object_priority": og_gs.structural_model_object_priority, +# "load": og_gs.load_structural_model, +# "is_saveable": og_gs.is_structural_model_saveable, +# "save": og_gs.save_structural_model, +# "builder": og_gs.StructuralModelBuilder, +# "crs": { +# "assign": og_gs.assign_brep_geographic_coordinate_system_info, +# "convert": og_gs.convert_brep_coordinate_reference_system, +# "create": og.create_brep_coordinate_system, +# }, +# "object_type": model, +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_structural_model, +# "save_light_viewable": g_v.save_light_viewable_structural_model, +# "inspector": og_inspector.inspect_brep, +# }, +# "TetrahedralSolid3D": { +# "class": og.TetrahedralSolid3D, +# "input_factory": og.TetrahedralSolidInputFactory3D, +# "output_factory": og.TetrahedralSolidOutputFactory3D, +# "additional_files": og.tetrahedral_solid_additional_files3D, +# "is_loadable": og.is_tetrahedral_solid_loadable3D, +# "object_priority": og.tetrahedral_solid_object_priority3D, +# "load": og.load_tetrahedral_solid3D, +# "is_saveable": og.is_tetrahedral_solid_saveable3D, +# "save": og.save_tetrahedral_solid3D, +# "builder": og.TetrahedralSolidBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, +# "create": og.create_solid_mesh_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, polyhedrons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_tetrahedral_solid3D, +# "save_light_viewable": g_v.save_light_viewable_tetrahedral_solid3D, +# "inspector": og_inspector.inspect_solid3D, +# }, +# "TriangulatedSurface2D": { +# "class": og.TriangulatedSurface2D, +# "input_factory": og.TriangulatedSurfaceInputFactory2D, +# "output_factory": og.TriangulatedSurfaceOutputFactory2D, +# "additional_files": og.triangulated_surface_additional_files2D, +# "is_loadable": og.is_triangulated_surface_loadable2D, +# "object_priority": og.triangulated_surface_object_priority2D, +# "load": og.load_triangulated_surface2D, +# "is_saveable": og.is_triangulated_surface_saveable2D, +# "save": og.save_triangulated_surface2D, +# "builder": og.TriangulatedSurfaceBuilder2D.create, +# "crs": { +# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, +# "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, +# "create": og.create_surface_mesh_coordinate_system2D, +# }, +# "object_type": mesh, +# "elements": [points, polygons], +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_triangulated_surface2D, +# "save_light_viewable": g_v.save_light_viewable_triangulated_surface2D, +# "inspector": og_inspector.inspect_surface2D, +# }, +# "TriangulatedSurface3D": { +# "class": og.TriangulatedSurface3D, +# "input_factory": og.TriangulatedSurfaceInputFactory3D, +# "output_factory": og.TriangulatedSurfaceOutputFactory3D, +# "additional_files": og.triangulated_surface_additional_files3D, +# "is_loadable": og.is_triangulated_surface_loadable3D, +# "object_priority": og.triangulated_surface_object_priority3D, +# "load": og.load_triangulated_surface3D, +# "is_saveable": og.is_triangulated_surface_saveable3D, +# "save": og.save_triangulated_surface3D, +# "builder": og.TriangulatedSurfaceBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_surface_mesh_coordinate_reference_system3D, +# "create": og.create_surface_mesh_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, polygons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_triangulated_surface3D, +# "save_light_viewable": g_v.save_light_viewable_triangulated_surface3D, +# "inspector": og_inspector.inspect_surface3D, +# }, +# "VertexSet": { +# "class": og.VertexSet, +# "input_factory": og.VertexSetInputFactory, +# "output_factory": og.VertexSetOutputFactory, +# "additional_files": og.vertex_set_additional_files, +# "is_loadable": og.is_vertex_set_loadable, +# "object_priority": og.vertex_set_object_priority, +# "load": og.load_vertex_set, +# "is_saveable": og.is_vertex_set_saveable, +# "save": og.save_vertex_set, +# "builder": og.VertexSetBuilder.create, +# "object_type": mesh, +# "is_3D": False, +# "is_viewable": False, +# }, +# } diff --git a/src/opengeodeweb_back/geode_objects/geode_brep.py b/src/opengeodeweb_back/geode_objects/geode_brep.py new file mode 100644 index 00000000..fd32f304 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_brep.py @@ -0,0 +1,43 @@ +import opengeode as og +import geode_viewables as viewables + +from ..geode_objects import GeodeObject + + +class GeodeBRep(GeodeObject): + brep: og.BRep + + def __init__(self, brep: og.BRep | None = None) -> None: + super().__init__(geode_type="BRep", object_type="model") + self.brep = brep if brep is not None else og.BRep() + + def builder(self) -> og.BRepBuilder: + return og.BRepBuilder(self.brep) + + @classmethod + def load(self, filename: str) -> GeodeBRep: + return GeodeBRep(og.load_brep(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFilesBRep: + return og.brep_additional_files(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_brep_loadable(filename) + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.brep_object_priority(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_brep_saveable(self.brep, filename) + + def save(self, filename: str) -> list[str]: + return og.save_brep(self.brep, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_brep(self.brep, filename_without_extension) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_brep(self.brep, filename_without_extension) diff --git a/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py b/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py index 888178c5..f9eb3550 100644 --- a/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py +++ b/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py @@ -8,4 +8,4 @@ def __post_init__(self) -> None: print(self, flush=True) filename: str - input_geode_object: str + input_geode_type: GeodeType diff --git a/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py b/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py index 31353997..67415c28 100644 --- a/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py +++ b/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py @@ -7,4 +7,4 @@ class GeographicCoordinateSystems(DataClassJsonMixin): def __post_init__(self) -> None: print(self, flush=True) - input_geode_object: str + input_geode_type: GeodeType diff --git a/src/opengeodeweb_back/routes/schemas/inspect_file.py b/src/opengeodeweb_back/routes/schemas/inspect_file.py index 0e0e36ea..46fcac0f 100644 --- a/src/opengeodeweb_back/routes/schemas/inspect_file.py +++ b/src/opengeodeweb_back/routes/schemas/inspect_file.py @@ -8,4 +8,4 @@ def __post_init__(self) -> None: print(self, flush=True) filename: str - input_geode_object: str + input_geode_type: GeodeType diff --git a/src/opengeodeweb_back/routes/schemas/missing_files.py b/src/opengeodeweb_back/routes/schemas/missing_files.py index 05a99f0a..822df519 100644 --- a/src/opengeodeweb_back/routes/schemas/missing_files.py +++ b/src/opengeodeweb_back/routes/schemas/missing_files.py @@ -8,4 +8,4 @@ def __post_init__(self) -> None: print(self, flush=True) filename: str - input_geode_object: str + input_geode_type: GeodeType diff --git a/src/opengeodeweb_back/routes/schemas/save_viewable_file.py b/src/opengeodeweb_back/routes/schemas/save_viewable_file.py index 754e5b32..29198a73 100644 --- a/src/opengeodeweb_back/routes/schemas/save_viewable_file.py +++ b/src/opengeodeweb_back/routes/schemas/save_viewable_file.py @@ -8,4 +8,4 @@ def __post_init__(self) -> None: print(self, flush=True) filename: str - input_geode_object: str + input_geode_type: GeodeType diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index 1f70ccd8..0f465a22 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -178,7 +178,7 @@ def create_data_folder_from_id(data_id: str) -> str: def save_all_viewables_and_return_info( - geode_object: str, + geode_type: GeodeType, data: object, data_entry: Data, data_path: str, @@ -224,7 +224,7 @@ def save_all_viewables_and_return_info( def generate_native_viewable_and_light_viewable_from_object( - geode_object: str, data: object + geode_type: GeodeType, data: object ) -> dict[str, str | list[str]]: data_entry = Data.create( geode_object=geode_object, @@ -235,7 +235,7 @@ def generate_native_viewable_and_light_viewable_from_object( def generate_native_viewable_and_light_viewable_from_file( - geode_object: str, input_filename: str + geode_type: GeodeType, input_filename: str ) -> dict[str, str | list[str]]: data_entry = Data.create( geode_object=geode_object, From 07ef56543c17e46e1fdb14670bf2ea532936d468 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Tue, 18 Nov 2025 15:41:26 +0100 Subject: [PATCH 02/21] wip --- requirements.in | 10 +- requirements.txt | 10 +- src/opengeodeweb_back/geode_functions.py | 227 +++---- .../geode_objects/__init__.py | 579 ++++++++++++++++++ .../geode_objects/geode_brep.py | 37 +- .../geode_object.py} | 81 ++- .../routes/blueprint_routes.py | 76 ++- .../geode_objects_and_output_extensions.py | 2 +- .../schemas/geographic_coordinate_systems.py | 2 +- .../routes/schemas/inspect_file.py | 2 +- .../routes/schemas/missing_files.py | 2 +- .../routes/schemas/save_viewable_file.py | 2 +- src/opengeodeweb_back/utils_functions.py | 86 ++- tests/conftest.py | 14 +- tests/test_geode_functions.py | 362 ++--------- tests/test_routes.py | 17 +- tests/test_utils_functions.py | 101 +-- 17 files changed, 969 insertions(+), 641 deletions(-) create mode 100644 src/opengeodeweb_back/geode_objects/__init__.py rename src/opengeodeweb_back/{geode_objects.py => geode_objects/geode_object.py} (95%) diff --git a/requirements.in b/requirements.in index ea33255c..77597074 100644 --- a/requirements.in +++ b/requirements.in @@ -1,8 +1,8 @@ -opengeode-core==15.29.2 -opengeode-io==7.4.2 -opengeode-inspector==6.8.2 -opengeode-geosciences==9.5.0 -opengeode-geosciencesio==5.8.1 +opengeode-core==15.30.2 +opengeode-io==7.4.6 +opengeode-inspector==6.8.6 +opengeode-geosciences==9.5.4 +opengeode-geosciencesio==5.8.6 geode-common==33.11.3 geode-viewables==3.3.2 flask[async]==3.1.2 diff --git a/requirements.txt b/requirements.txt index fea82e6e..0d6a8e5a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,7 +31,7 @@ markupsafe>=3 # flask # jinja2 # werkzeug -opengeode-core==15.29.2 +opengeode-core==15.30.2 # via # -r requirements.in # geode-common @@ -40,16 +40,16 @@ opengeode-core==15.29.2 # opengeode-geosciencesio # opengeode-inspector # opengeode-io -opengeode-geosciences==9.5.0 +opengeode-geosciences==9.5.4 # via # -r requirements.in # geode-viewables # opengeode-geosciencesio -opengeode-geosciencesio==5.8.1 +opengeode-geosciencesio==5.8.6 # via -r requirements.in -opengeode-inspector==6.8.2 +opengeode-inspector==6.8.6 # via -r requirements.in -opengeode-io==7.4.2 +opengeode-io==7.4.6 # via # -r requirements.in # geode-viewables diff --git a/src/opengeodeweb_back/geode_functions.py b/src/opengeodeweb_back/geode_functions.py index 90e86ef6..486bd8b9 100644 --- a/src/opengeodeweb_back/geode_functions.py +++ b/src/opengeodeweb_back/geode_functions.py @@ -3,17 +3,19 @@ # Third party imports import opengeode_geosciences as og_gs -import opengeode as og +import opengeode as og import werkzeug import flask from typing import Any # Local application imports -from .geode_objects import geode_objects,GeodeType, GeodeObject, to_geode_type +from .geode_objects import geode_objects +from .geode_objects.geode_object import GeodeType, GeodeObject, to_geode_type from . import utils_functions from opengeodeweb_microservice.database.data import Data from opengeodeweb_microservice.database.connection import get_session + def data_file_path(data_id: str, filename: str | None) -> str: data_folder_path = flask.current_app.config["DATA_FOLDER_PATH"] data_path = os.path.join(data_folder_path, data_id) @@ -30,7 +32,9 @@ def load_data(data_id: str) -> GeodeObject: file_absolute_path = data_file_path(data_id, data_entry.native_file_name) print("Loading file: ", file_absolute_path) print("File exists: ", os.path.exists(file_absolute_path)) - return geode_objects[to_geode_type(data_entry.geode_object)].load(file_absolute_path) + return geode_objects[to_geode_type(data_entry.geode_object)].load( + file_absolute_path + ) def get_data_info(data_id: str) -> Data: @@ -46,6 +50,31 @@ def upload_file_path(filename: str) -> str: return os.path.abspath(os.path.join(upload_folder, secure_filename)) +def geode_object_output_extensions( + geode_object: GeodeObject, +) -> dict[GeodeType, dict[str, bool]]: + results: dict[GeodeType, dict[str, bool]] = {} + for mixin_geode_object in geode_objects[geode_object.geode_type()].__mro__: + output_extensions_method = getattr( + mixin_geode_object, "output_extensions", None + ) + if output_extensions_method is None: + continue + output_extensions = output_extensions_method.__func__(mixin_geode_object) + if output_extensions is None: + continue + object_output_extensions: dict[str, bool] = {} + is_saveable_method = getattr(mixin_geode_object, "is_saveable") + for output_extension in output_extensions: + bool_is_saveable = is_saveable_method( + geode_object, f"test.{output_extension}" + ) + object_output_extensions[output_extension] = bool_is_saveable + if hasattr(mixin_geode_object, "geode_type"): + results[mixin_geode_object.geode_type()] = object_output_extensions + return results + + # def assign_crs(geode_type: GeodeType, data, crs_name: str, info): # builder = create_builder(geode_object, data) # geode_objects[geode_type].["crs"]["assign"](data, builder, crs_name, info) @@ -69,154 +98,56 @@ def upload_file_path(filename: str) -> str: # ) -def filter_geode_objects(key: str | None = None)-> list[GeodeType]: - filtered_geode_objects = [] - for geode_object, value in geode_objects.items(): - if key != None and key != "": - if key in value: - if type(value[key]) == bool: - filtered_geode_objects.append(geode_object) - else: - filtered_geode_objects.append(geode_object) - else: - filtered_geode_objects.append(geode_object) - filtered_geode_objects.sort() - return filtered_geode_objects - - -def list_input_extensions(key: str | None = None) -> list[str]: - extensions_list = [] - for geode_object in filter_geode_objects(key): - extensions_list += geode_object_input_extensions(geode_object) - extensions_list = list(set(extensions_list)) - extensions_list.sort() - return extensions_list - - -def has_creator(geode_type: GeodeType, extension: str): - return input_factory(geode_object).has_creator(extension) - - -def list_geode_objects( - file_absolute_path: str, - key: str | None = None, -): - return_dict = {} - file_extension = utils_functions.extension_from_filename( - os.path.basename(file_absolute_path) - ) - geode_objects_filtered_list = filter_geode_objects(key) - for geode_object in geode_objects_filtered_list: - if has_creator(geode_object, file_extension): - loadability_score = is_loadable(geode_object, file_absolute_path) - priority_score = object_priority(geode_object, file_absolute_path) - return_dict[geode_object] = { - "is_loadable": loadability_score, - "object_priority": priority_score, - } - return return_dict - - -def geode_objects_output_extensions(geode_type: GeodeType, data): - geode_objects_output_extensions_dict = {} - output_extensions = geode_object_output_extensions(geode_object) - extensions_dict = {} - for output_extension in output_extensions: - bool_is_saveable = is_saveable(geode_object, data, f"test.{output_extension}") - extensions_dict[output_extension] = {"is_saveable": bool_is_saveable} - geode_objects_output_extensions_dict[geode_object] = extensions_dict - - if "parent" in geode_objects[geode_type]..keys(): - parent_geode_object = geode_objects[geode_type].["parent"] - geode_objects_output_extensions_dict.update( - geode_objects_output_extensions(parent_geode_object, data) - ) - return geode_objects_output_extensions_dict - - -def get_inspector_children(obj): - new_object = {} - - if "inspection_type" in dir(obj): - new_object["title"] = obj.inspection_type() - new_object["nb_issues"] = 0 - new_object["children"] = [] - for child in dir(obj): - if not child.startswith("__") and not child in [ - "inspection_type", - "string", - ]: - child_instance = obj.__getattribute__(child) - child_object = get_inspector_children(child_instance) - new_object["children"].append(child_object) - new_object["nb_issues"] += child_object["nb_issues"] - else: - new_object["title"] = obj.description() - nb_issues = obj.nb_issues() - new_object["nb_issues"] = nb_issues - if nb_issues > 0: - issues = obj.string().split("\n") - new_object["issues"] = issues - return new_object - - -def geographic_coordinate_systems(geode_type: GeodeType): - if is_3D(geode_object): - return og_gs.GeographicCoordinateSystem3D.geographic_coordinate_systems() - else: - return og_gs.GeographicCoordinateSystem2D.geographic_coordinate_systems() - - -def geographic_coordinate_systems_info(geode_type: GeodeType, crs): - if is_3D(geode_object): - return og_gs.GeographicCoordinateSystemInfo3D( - crs["authority"], crs["code"], crs["name"] - ) - else: - return og_gs.GeographicCoordinateSystemInfo2D( - crs["authority"], crs["code"], crs["name"] - ) - - -def coordinate_system(geode_type: GeodeType, coordinate_system): - return og.CoordinateSystem2D( - [ - og.Vector2D( - og.Point2D( - [coordinate_system["origin_x"], coordinate_system["origin_y"]] - ), - og.Point2D( - [coordinate_system["point_1_x"], coordinate_system["point_1_y"]] - ), - ), - og.Vector2D( - og.Point2D( - [coordinate_system["origin_x"], coordinate_system["origin_y"]] - ), - og.Point2D( - [coordinate_system["point_2_x"], coordinate_system["point_2_y"]] - ), - ), - ], - og.Point2D([coordinate_system["origin_x"], coordinate_system["origin_y"]]), - ) +# def geographic_coordinate_systems_info(geode_type: GeodeType, crs): +# if is_3D(geode_object): +# return og_gs.GeographicCoordinateSystemInfo3D( +# crs["authority"], crs["code"], crs["name"] +# ) +# else: +# return og_gs.GeographicCoordinateSystemInfo2D( +# crs["authority"], crs["code"], crs["name"] +# ) + + +# def coordinate_system(geode_type: GeodeType, coordinate_system): +# return og.CoordinateSystem2D( +# [ +# og.Vector2D( +# og.Point2D( +# [coordinate_system["origin_x"], coordinate_system["origin_y"]] +# ), +# og.Point2D( +# [coordinate_system["point_1_x"], coordinate_system["point_1_y"]] +# ), +# ), +# og.Vector2D( +# og.Point2D( +# [coordinate_system["origin_x"], coordinate_system["origin_y"]] +# ), +# og.Point2D( +# [coordinate_system["point_2_x"], coordinate_system["point_2_y"]] +# ), +# ), +# ], +# og.Point2D([coordinate_system["origin_x"], coordinate_system["origin_y"]]), +# ) -def assign_geographic_coordinate_system_info(geode_type: GeodeType, data, input_crs): - info = geographic_coordinate_systems_info(geode_object, input_crs) - assign_crs(geode_object, data, input_crs["name"], info) +# def assign_geographic_coordinate_system_info(geode_type: GeodeType, data, input_crs): +# info = geographic_coordinate_systems_info(geode_object, input_crs) +# assign_crs(geode_object, data, input_crs["name"], info) -def convert_geographic_coordinate_system_info(geode_type: GeodeType, data, output_crs): - info = geographic_coordinate_systems_info(geode_object, output_crs) - convert_crs(geode_object, data, output_crs["name"], info) +# def convert_geographic_coordinate_system_info(geode_type: GeodeType, data, output_crs): +# info = geographic_coordinate_systems_info(geode_object, output_crs) +# convert_crs(geode_object, data, output_crs["name"], info) -def create_coordinate_system( - geode_type: GeodeType, data, name, input_coordinate_points, output_coordinate_points -): - input_coordiante_system = coordinate_system(geode_object, input_coordinate_points) - output_coordiante_system = coordinate_system(geode_object, output_coordinate_points) - create_crs( - geode_object, data, name, input_coordiante_system, output_coordiante_system - ) +# def create_coordinate_system( +# geode_type: GeodeType, data, name, input_coordinate_points, output_coordinate_points +# ): +# input_coordiante_system = coordinate_system(geode_object, input_coordinate_points) +# output_coordiante_system = coordinate_system(geode_object, output_coordinate_points) +# create_crs( +# geode_object, data, name, input_coordiante_system, output_coordiante_system +# ) diff --git a/src/opengeodeweb_back/geode_objects/__init__.py b/src/opengeodeweb_back/geode_objects/__init__.py new file mode 100644 index 00000000..6084659e --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/__init__.py @@ -0,0 +1,579 @@ +# Standard library imports +from __future__ import annotations +from abc import ABC, abstractmethod +from typing import Literal, Any, get_args, cast + +# Third party imports +import opengeode as og +import opengeode_io as og_io +import opengeode_inspector as og_inspector +import opengeode_geosciences as og_gs +import opengeode_geosciencesio as og_gs_io +import geode_viewables as viewables + +# Local application imports +from .geode_object import GeodeType, GeodeObject +from .geode_brep import GeodeBRep + + +geode_objects: dict[GeodeType, type[GeodeObject]] = {"BRep": GeodeBRep} + + +mesh = "mesh" +model = "model" + +points = "points" +edges = "edges" +polygons = "polygons" +polyhedrons = "polyhedrons" + + +# def geode_objects_dict(): +# return { +# "BRep": { +# "class": og.BRep, +# "input_factory": og.BRepInputFactory, +# "output_factory": og.BRepOutputFactory, +# "additional_files": og.brep_additional_files, +# "is_loadable": og.is_brep_loadable, +# "object_priority": og.brep_object_priority, +# "load": og.load_brep, +# "is_saveable": og.is_brep_saveable, +# "save": og.save_brep, +# "builder": og.BRepBuilder, +# "crs": { +# "assign": og_gs.assign_brep_geographic_coordinate_system_info, +# "convert": og_gs.convert_brep_coordinate_reference_system, +# "create": og.create_brep_coordinate_system, +# }, +# "object_type": model, +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_brep, +# "save_light_viewable": g_v.save_light_viewable_brep, +# "inspector": og_inspector.inspect_brep, +# }, +# "CrossSection": { +# "parent": "Section", +# "class": og_gs.CrossSection, +# "input_factory": og_gs.CrossSectionInputFactory, +# "output_factory": og_gs.CrossSectionOutputFactory, +# "additional_files": og_gs.cross_section_additional_files, +# "is_loadable": og_gs.is_cross_section_loadable, +# "object_priority": og_gs.cross_section_object_priority, +# "load": og_gs.load_cross_section, +# "is_saveable": og_gs.is_cross_section_saveable, +# "save": og_gs.save_cross_section, +# "builder": og_gs.CrossSectionBuilder, +# "crs": { +# "assign": og_gs.assign_section_geographic_coordinate_system_info, +# "convert": og_gs.convert_section_coordinate_reference_system, +# "create": og.create_section_coordinate_system, +# }, +# "object_type": model, +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_cross_section, +# "save_light_viewable": g_v.save_light_viewable_cross_section, +# "inspector": og_inspector.inspect_section, +# }, +# "EdgedCurve2D": { +# "class": og.EdgedCurve2D, +# "input_factory": og.EdgedCurveInputFactory2D, +# "output_factory": og.EdgedCurveOutputFactory2D, +# "additional_files": og.edged_curve_additional_files2D, +# "is_loadable": og.is_edged_curve_loadable2D, +# "object_priority": og.edged_curve_object_priority2D, +# "load": og.load_edged_curve2D, +# "is_saveable": og.is_edged_curve_saveable2D, +# "save": og.save_edged_curve2D, +# "builder": og.EdgedCurveBuilder2D.create, +# "crs": { +# "assign": og_gs.assign_edged_curve_geographic_coordinate_system_info2D, +# "convert": og_gs.convert_edged_curve_coordinate_reference_system2D, +# "create": og.create_edged_curve_coordinate_system2D, +# }, +# "object_type": mesh, +# "elements": [points, edges], +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_edged_curve2D, +# "save_light_viewable": g_v.save_light_viewable_edged_curve2D, +# "inspector": og_inspector.inspect_edged_curve2D, +# }, +# "EdgedCurve3D": { +# "class": og.EdgedCurve3D, +# "input_factory": og.EdgedCurveInputFactory3D, +# "output_factory": og.EdgedCurveOutputFactory3D, +# "additional_files": og.edged_curve_additional_files3D, +# "is_loadable": og.is_edged_curve_loadable3D, +# "object_priority": og.edged_curve_object_priority3D, +# "load": og.load_edged_curve3D, +# "is_saveable": og.is_edged_curve_saveable3D, +# "save": og.save_edged_curve3D, +# "builder": og.EdgedCurveBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_edged_curve_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_edged_curve_coordinate_reference_system3D, +# "create": og.create_edged_curve_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, edges], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_edged_curve3D, +# "save_light_viewable": g_v.save_light_viewable_edged_curve3D, +# "inspector": og_inspector.inspect_edged_curve3D, +# }, +# "Graph": { +# "class": og.Graph, +# "input_factory": og.GraphInputFactory, +# "output_factory": og.GraphOutputFactory, +# "additional_files": og.graph_additional_files, +# "is_loadable": og.is_graph_loadable, +# "object_priority": og.graph_object_priority, +# "load": og.load_graph, +# "is_saveable": og.is_graph_saveable, +# "save": og.save_graph, +# "builder": og.GraphBuilder.create, +# "object_type": mesh, +# "is_3D": False, +# "is_viewable": False, +# }, +# "HybridSolid3D": { +# "class": og.HybridSolid3D, +# "input_factory": og.HybridSolidInputFactory3D, +# "output_factory": og.HybridSolidOutputFactory3D, +# "additional_files": og.hybrid_solid_additional_files3D, +# "is_loadable": og.is_hybrid_solid_loadable3D, +# "object_priority": og.hybrid_solid_object_priority3D, +# "load": og.load_hybrid_solid3D, +# "is_saveable": og.is_hybrid_solid_saveable3D, +# "save": og.save_hybrid_solid3D, +# "builder": og.HybridSolidBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, +# "create": og.create_solid_mesh_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, polyhedrons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_hybrid_solid3D, +# "save_light_viewable": g_v.save_light_viewable_hybrid_solid3D, +# "inspector": og_inspector.inspect_solid3D, +# }, +# "ImplicitCrossSection": { +# "parent": "CrossSection", +# "class": og_gs.ImplicitCrossSection, +# "input_factory": og_gs.ImplicitCrossSectionInputFactory, +# "output_factory": og_gs.ImplicitCrossSectionOutputFactory, +# "additional_files": og_gs.implicit_cross_section_additional_files, +# "is_loadable": og_gs.is_implicit_cross_section_loadable, +# "object_priority": og_gs.implicit_cross_section_object_priority, +# "load": og_gs.load_implicit_cross_section, +# "is_saveable": og_gs.is_implicit_cross_section_saveable, +# "save": og_gs.save_implicit_cross_section, +# "builder": og_gs.ImplicitCrossSectionBuilder, +# "crs": { +# "assign": og_gs.assign_section_geographic_coordinate_system_info, +# "convert": og_gs.convert_section_coordinate_reference_system, +# "create": og.create_section_coordinate_system, +# }, +# "object_type": model, +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_implicit_cross_section, +# "save_light_viewable": g_v.save_light_viewable_implicit_cross_section, +# "inspector": og_inspector.inspect_section, +# }, +# "ImplicitStructuralModel": { +# "parent": "StructuralModel", +# "class": og_gs.ImplicitStructuralModel, +# "input_factory": og_gs.ImplicitStructuralModelInputFactory, +# "output_factory": og_gs.ImplicitStructuralModelOutputFactory, +# "additional_files": og_gs.implicit_structural_model_additional_files, +# "is_loadable": og_gs.is_implicit_structural_model_loadable, +# "object_priority": og_gs.implicit_structural_model_object_priority, +# "load": og_gs.load_implicit_structural_model, +# "is_saveable": og_gs.is_implicit_structural_model_saveable, +# "save": og_gs.save_implicit_structural_model, +# "builder": og_gs.ImplicitStructuralModelBuilder, +# "crs": { +# "assign": og_gs.assign_brep_geographic_coordinate_system_info, +# "convert": og_gs.convert_brep_coordinate_reference_system, +# "create": og.create_brep_coordinate_system, +# }, +# "object_type": model, +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_implicit_structural_model, +# "save_light_viewable": g_v.save_light_viewable_implicit_structural_model, +# "inspector": og_inspector.inspect_brep, +# }, +# "LightRegularGrid2D": { +# "class": og.LightRegularGrid2D, +# "input_factory": og.LightRegularGridInputFactory2D, +# "output_factory": og.LightRegularGridOutputFactory2D, +# "additional_files": og.light_regular_grid_additional_files2D, +# "is_loadable": og.is_light_regular_grid_loadable2D, +# "object_priority": og.light_regular_grid_object_priority2D, +# "load": og.load_light_regular_grid2D, +# "is_saveable": og.is_light_regular_grid_saveable2D, +# "save": og.save_light_regular_grid2D, +# "object_type": mesh, +# "elements": [points, polygons], +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_light_regular_grid2D, +# "save_light_viewable": g_v.save_light_viewable_light_regular_grid2D, +# }, +# "LightRegularGrid3D": { +# "class": og.LightRegularGrid3D, +# "input_factory": og.LightRegularGridInputFactory3D, +# "output_factory": og.LightRegularGridOutputFactory3D, +# "additional_files": og.light_regular_grid_additional_files3D, +# "is_loadable": og.is_light_regular_grid_loadable3D, +# "object_priority": og.light_regular_grid_object_priority3D, +# "load": og.load_light_regular_grid3D, +# "is_saveable": og.is_light_regular_grid_saveable3D, +# "save": og.save_light_regular_grid3D, +# "object_type": mesh, +# "elements": [points, polyhedrons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_light_regular_grid3D, +# "save_light_viewable": g_v.save_light_viewable_light_regular_grid3D, +# }, +# "PointSet2D": { +# "class": og.PointSet2D, +# "input_factory": og.PointSetInputFactory2D, +# "output_factory": og.PointSetOutputFactory2D, +# "additional_files": og.point_set_additional_files2D, +# "is_loadable": og.is_point_set_loadable2D, +# "object_priority": og.point_set_object_priority2D, +# "load": og.load_point_set2D, +# "is_saveable": og.is_point_set_saveable2D, +# "save": og.save_point_set2D, +# "builder": og.PointSetBuilder2D.create, +# "crs": { +# "assign": og_gs.assign_point_set_geographic_coordinate_system_info2D, +# "convert": og_gs.convert_point_set_coordinate_reference_system2D, +# "create": og.create_point_set_coordinate_system2D, +# }, +# "object_type": mesh, +# "elements": [points], +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_point_set2D, +# "save_light_viewable": g_v.save_light_viewable_point_set2D, +# "inspector": og_inspector.inspect_point_set2D, +# }, +# "PointSet3D": { +# "class": og.PointSet3D, +# "input_factory": og.PointSetInputFactory3D, +# "output_factory": og.PointSetOutputFactory3D, +# "additional_files": og.point_set_additional_files3D, +# "is_loadable": og.is_point_set_loadable3D, +# "object_priority": og.point_set_object_priority3D, +# "load": og.load_point_set3D, +# "is_saveable": og.is_point_set_saveable3D, +# "save": og.save_point_set3D, +# "builder": og.PointSetBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_point_set_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_point_set_coordinate_reference_system3D, +# "create": og.create_point_set_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_point_set3D, +# "save_light_viewable": g_v.save_light_viewable_point_set3D, +# "inspector": og_inspector.inspect_point_set3D, +# }, +# "PolygonalSurface2D": { +# "class": og.PolygonalSurface2D, +# "input_factory": og.PolygonalSurfaceInputFactory2D, +# "output_factory": og.PolygonalSurfaceOutputFactory2D, +# "additional_files": og.polygonal_surface_additional_files2D, +# "is_loadable": og.is_polygonal_surface_loadable2D, +# "object_priority": og.polygonal_surface_object_priority2D, +# "load": og.load_polygonal_surface2D, +# "is_saveable": og.is_polygonal_surface_saveable2D, +# "save": og.save_polygonal_surface2D, +# "builder": og.PolygonalSurfaceBuilder2D.create, +# "crs": { +# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, +# "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, +# "create": og.create_surface_mesh_coordinate_system2D, +# }, +# "object_type": mesh, +# "elements": [points, polygons], +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_polygonal_surface2D, +# "save_light_viewable": g_v.save_light_viewable_polygonal_surface2D, +# "inspector": og_inspector.inspect_surface2D, +# }, +# "PolygonalSurface3D": { +# "class": og.PolygonalSurface3D, +# "input_factory": og.PolygonalSurfaceInputFactory3D, +# "output_factory": og.PolygonalSurfaceOutputFactory3D, +# "additional_files": og.polygonal_surface_additional_files3D, +# "is_loadable": og.is_polygonal_surface_loadable3D, +# "object_priority": og.polygonal_surface_object_priority3D, +# "load": og.load_polygonal_surface3D, +# "is_saveable": og.is_polygonal_surface_saveable3D, +# "save": og.save_polygonal_surface3D, +# "builder": og.PolygonalSurfaceBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_surface_mesh_coordinate_reference_system3D, +# "create": og.create_surface_mesh_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, polygons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_polygonal_surface3D, +# "save_light_viewable": g_v.save_light_viewable_polygonal_surface3D, +# "inspector": og_inspector.inspect_surface3D, +# }, +# "PolyhedralSolid3D": { +# "class": og.PolyhedralSolid3D, +# "input_factory": og.PolyhedralSolidInputFactory3D, +# "output_factory": og.PolyhedralSolidOutputFactory3D, +# "additional_files": og.polyhedral_solid_additional_files3D, +# "is_loadable": og.is_polyhedral_solid_loadable3D, +# "object_priority": og.polyhedral_solid_object_priority3D, +# "load": og.load_polyhedral_solid3D, +# "is_saveable": og.is_polyhedral_solid_saveable3D, +# "save": og.save_polyhedral_solid3D, +# "builder": og.PolyhedralSolidBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, +# "create": og.create_solid_mesh_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, polyhedrons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_polyhedral_solid3D, +# "save_light_viewable": g_v.save_light_viewable_polyhedral_solid3D, +# "inspector": og_inspector.inspect_solid3D, +# }, +# "RasterImage2D": { +# "class": og.RasterImage2D, +# "input_factory": og.RasterImageInputFactory2D, +# "output_factory": og.RasterImageOutputFactory2D, +# "additional_files": og.raster_image_additional_files2D, +# "is_loadable": og.is_raster_image_loadable2D, +# "object_priority": og.raster_image_object_priority2D, +# "load": og.load_raster_image2D, +# "is_saveable": og.is_raster_image_saveable2D, +# "save": og.save_raster_image2D, +# "object_type": mesh, +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_raster_image2D, +# }, +# "RasterImage3D": { +# "class": og.RasterImage3D, +# "input_factory": og.RasterImageInputFactory3D, +# "output_factory": og.RasterImageOutputFactory3D, +# "additional_files": og.raster_image_additional_files3D, +# "is_loadable": og.is_raster_image_loadable3D, +# "object_priority": og.raster_image_object_priority3D, +# "load": og.load_raster_image3D, +# "is_saveable": og.is_raster_image_saveable3D, +# "save": og.save_raster_image3D, +# "object_type": mesh, +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_raster_image3D, +# }, +# "RegularGrid2D": { +# "class": og.RegularGrid2D, +# "input_factory": og.RegularGridInputFactory2D, +# "output_factory": og.RegularGridOutputFactory2D, +# "additional_files": og.regular_grid_additional_files2D, +# "is_loadable": og.is_regular_grid_loadable2D, +# "object_priority": og.regular_grid_object_priority2D, +# "load": og.load_regular_grid2D, +# "is_saveable": og.is_regular_grid_saveable2D, +# "save": og.save_regular_grid2D, +# "builder": og.RegularGridBuilder2D.create, +# "crs": { +# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, +# "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, +# "create": og.create_surface_mesh_coordinate_system2D, +# }, +# "object_type": mesh, +# "elements": [points, polygons], +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_regular_grid2D, +# "save_light_viewable": g_v.save_light_viewable_regular_grid2D, +# }, +# "RegularGrid3D": { +# "class": og.RegularGrid3D, +# "input_factory": og.RegularGridInputFactory3D, +# "output_factory": og.RegularGridOutputFactory3D, +# "additional_files": og.regular_grid_additional_files3D, +# "is_loadable": og.is_regular_grid_loadable3D, +# "object_priority": og.regular_grid_object_priority3D, +# "load": og.load_regular_grid3D, +# "is_saveable": og.is_regular_grid_saveable3D, +# "save": og.save_regular_grid3D, +# "builder": og.RegularGridBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, +# "create": og.create_surface_mesh_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, polyhedrons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_regular_grid3D, +# "save_light_viewable": g_v.save_light_viewable_regular_grid3D, +# }, +# "Section": { +# "class": og.Section, +# "input_factory": og.SectionInputFactory, +# "output_factory": og.SectionOutputFactory, +# "additional_files": og.section_additional_files, +# "is_loadable": og.is_section_loadable, +# "object_priority": og.section_object_priority, +# "load": og.load_section, +# "is_saveable": og.is_section_saveable, +# "save": og.save_section, +# "builder": og.SectionBuilder, +# "crs": { +# "assign": og_gs.assign_section_geographic_coordinate_system_info, +# "convert": og_gs.convert_section_coordinate_reference_system, +# "create": og.create_section_coordinate_system, +# }, +# "object_type": model, +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_section, +# "save_light_viewable": g_v.save_light_viewable_section, +# "inspector": og_inspector.inspect_section, +# }, +# "StructuralModel": { +# "parent": "BRep", +# "class": og_gs.StructuralModel, +# "input_factory": og_gs.StructuralModelInputFactory, +# "output_factory": og_gs.StructuralModelOutputFactory, +# "additional_files": og_gs.structural_model_additional_files, +# "is_loadable": og_gs.is_structural_model_loadable, +# "object_priority": og_gs.structural_model_object_priority, +# "load": og_gs.load_structural_model, +# "is_saveable": og_gs.is_structural_model_saveable, +# "save": og_gs.save_structural_model, +# "builder": og_gs.StructuralModelBuilder, +# "crs": { +# "assign": og_gs.assign_brep_geographic_coordinate_system_info, +# "convert": og_gs.convert_brep_coordinate_reference_system, +# "create": og.create_brep_coordinate_system, +# }, +# "object_type": model, +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_structural_model, +# "save_light_viewable": g_v.save_light_viewable_structural_model, +# "inspector": og_inspector.inspect_brep, +# }, +# "TetrahedralSolid3D": { +# "class": og.TetrahedralSolid3D, +# "input_factory": og.TetrahedralSolidInputFactory3D, +# "output_factory": og.TetrahedralSolidOutputFactory3D, +# "additional_files": og.tetrahedral_solid_additional_files3D, +# "is_loadable": og.is_tetrahedral_solid_loadable3D, +# "object_priority": og.tetrahedral_solid_object_priority3D, +# "load": og.load_tetrahedral_solid3D, +# "is_saveable": og.is_tetrahedral_solid_saveable3D, +# "save": og.save_tetrahedral_solid3D, +# "builder": og.TetrahedralSolidBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, +# "create": og.create_solid_mesh_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, polyhedrons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_tetrahedral_solid3D, +# "save_light_viewable": g_v.save_light_viewable_tetrahedral_solid3D, +# "inspector": og_inspector.inspect_solid3D, +# }, +# "TriangulatedSurface2D": { +# "class": og.TriangulatedSurface2D, +# "input_factory": og.TriangulatedSurfaceInputFactory2D, +# "output_factory": og.TriangulatedSurfaceOutputFactory2D, +# "additional_files": og.triangulated_surface_additional_files2D, +# "is_loadable": og.is_triangulated_surface_loadable2D, +# "object_priority": og.triangulated_surface_object_priority2D, +# "load": og.load_triangulated_surface2D, +# "is_saveable": og.is_triangulated_surface_saveable2D, +# "save": og.save_triangulated_surface2D, +# "builder": og.TriangulatedSurfaceBuilder2D.create, +# "crs": { +# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, +# "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, +# "create": og.create_surface_mesh_coordinate_system2D, +# }, +# "object_type": mesh, +# "elements": [points, polygons], +# "is_3D": False, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_triangulated_surface2D, +# "save_light_viewable": g_v.save_light_viewable_triangulated_surface2D, +# "inspector": og_inspector.inspect_surface2D, +# }, +# "TriangulatedSurface3D": { +# "class": og.TriangulatedSurface3D, +# "input_factory": og.TriangulatedSurfaceInputFactory3D, +# "output_factory": og.TriangulatedSurfaceOutputFactory3D, +# "additional_files": og.triangulated_surface_additional_files3D, +# "is_loadable": og.is_triangulated_surface_loadable3D, +# "object_priority": og.triangulated_surface_object_priority3D, +# "load": og.load_triangulated_surface3D, +# "is_saveable": og.is_triangulated_surface_saveable3D, +# "save": og.save_triangulated_surface3D, +# "builder": og.TriangulatedSurfaceBuilder3D.create, +# "crs": { +# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info3D, +# "convert": og_gs.convert_surface_mesh_coordinate_reference_system3D, +# "create": og.create_surface_mesh_coordinate_system3D, +# }, +# "object_type": mesh, +# "elements": [points, polygons], +# "is_3D": True, +# "is_viewable": True, +# "save_viewable": g_v.save_viewable_triangulated_surface3D, +# "save_light_viewable": g_v.save_light_viewable_triangulated_surface3D, +# "inspector": og_inspector.inspect_surface3D, +# }, +# "VertexSet": { +# "class": og.VertexSet, +# "input_factory": og.VertexSetInputFactory, +# "output_factory": og.VertexSetOutputFactory, +# "additional_files": og.vertex_set_additional_files, +# "is_loadable": og.is_vertex_set_loadable, +# "object_priority": og.vertex_set_object_priority, +# "load": og.load_vertex_set, +# "is_saveable": og.is_vertex_set_saveable, +# "save": og.save_vertex_set, +# "builder": og.VertexSetBuilder.create, +# "object_type": mesh, +# "is_3D": False, +# "is_viewable": False, +# }, +# } diff --git a/src/opengeodeweb_back/geode_objects/geode_brep.py b/src/opengeodeweb_back/geode_objects/geode_brep.py index fd32f304..04170317 100644 --- a/src/opengeodeweb_back/geode_objects/geode_brep.py +++ b/src/opengeodeweb_back/geode_objects/geode_brep.py @@ -1,35 +1,62 @@ import opengeode as og import geode_viewables as viewables -from ..geode_objects import GeodeObject +from .geode_object import GeodeObject, GeodeType, ViewerType class GeodeBRep(GeodeObject): brep: og.BRep def __init__(self, brep: og.BRep | None = None) -> None: - super().__init__(geode_type="BRep", object_type="model") self.brep = brep if brep is not None else og.BRep() + super().__init__(self.brep) + + @classmethod + def geode_type(cls) -> GeodeType: + return "BRep" + + @classmethod + def viewer_type(cls) -> ViewerType: + return "model" + + def native_extension(self) -> str: + return self.brep.native_extension() + + @classmethod + def is_3D(cls) -> bool: + return True + + @classmethod + def is_viewable(cls) -> bool: + return True def builder(self) -> og.BRepBuilder: return og.BRepBuilder(self.brep) @classmethod - def load(self, filename: str) -> GeodeBRep: + def load(self, filename: str) -> "GeodeBRep": return GeodeBRep(og.load_brep(filename)) @classmethod - def additional_files(cls, filename: str) -> og.AdditionalFilesBRep: + def additional_files(cls, filename: str) -> og.AdditionalFiles: return og.brep_additional_files(filename) @classmethod def is_loadable(cls, filename: str) -> og.Percentage: return og.is_brep_loadable(filename) + @classmethod + def input_extensions(cls) -> list[str]: + return og.BRepInputFactory.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.BRepOutputFactory.list_creators() + @classmethod def object_priority(cls, filename: str) -> int: return og.brep_object_priority(filename) - + def is_saveable(self, filename: str) -> bool: return og.is_brep_saveable(self.brep, filename) diff --git a/src/opengeodeweb_back/geode_objects.py b/src/opengeodeweb_back/geode_objects/geode_object.py similarity index 95% rename from src/opengeodeweb_back/geode_objects.py rename to src/opengeodeweb_back/geode_objects/geode_object.py index 5e7a84bb..2321e103 100644 --- a/src/opengeodeweb_back/geode_objects.py +++ b/src/opengeodeweb_back/geode_objects/geode_object.py @@ -1,95 +1,95 @@ # Standard library imports +from __future__ import annotations from abc import ABC, abstractmethod from typing import Literal, Any, get_args, cast -from __future__ import annotations # Third party imports -import opengeode as og -import opengeode_io as og_io -import opengeode_inspector as og_inspector -import opengeode_geosciences as og_gs -import opengeode_geosciencesio as og_gs_io -import geode_viewables as viewables +import opengeode as og +import opengeode_io as og_io +import opengeode_inspector as og_inspector +import opengeode_geosciences as og_gs +import opengeode_geosciencesio as og_gs_io +import geode_viewables as viewables # Local application imports -from .geode_objects.geode_brep import GeodeBRep GeodeType = Literal["BRep"] + def to_geode_type(value: str) -> GeodeType: - allowed = get_args(GeodeType) + allowed = get_args(GeodeType) if value not in allowed: raise ValueError(f"Invalid GeodeType: {value!r}. Must be one of {allowed}") return cast(GeodeType, value) + ViewerType = Literal["mesh", "model"] class GeodeObject(ABC): - geode_type: GeodeType - object_type: ViewerType - is_3D: bool - is_viewable: bool + identifier: og.Identifier - def __init__(self, geode_type: GeodeType, object_type: ViewerType, is_3D: bool = True, is_viewable: bool = True) -> None: - self.object_type = object_type - self.is_3D = is_3D - self.is_viewable = is_viewable + def __init__(self, identifier: og.Identifier | None = None) -> None: + self.identifier = identifier if identifier is not None else og.Identifier() + @classmethod @abstractmethod - def builder(self) -> Any: - ... + def geode_type(cls) -> GeodeType: ... @classmethod @abstractmethod - def load(self, filename: str) -> GeodeObject: - ... + def viewer_type(cls) -> ViewerType: ... @classmethod @abstractmethod - def additional_files(cls, filename: str) -> Any: - ... + def is_3D(cls) -> bool: ... @classmethod @abstractmethod - def is_loadable(cls, filename: str) -> og.Percentage: - ... + def is_viewable(cls) -> bool: ... + + @abstractmethod + def builder(self) -> Any: ... @classmethod @abstractmethod - def input_extensions(cls) -> list[str]: - ... + def is_loadable(cls, filename: str) -> og.Percentage: ... @classmethod @abstractmethod - def object_priority(cls, filename: str) -> int: - ... + def load(cls, filename: str) -> GeodeObject: ... @classmethod @abstractmethod - def output_extensions(cls) -> list[str]: - ... + def additional_files(cls, filename: str) -> og.AdditionalFiles: ... + + @abstractmethod + def native_extension(cls) -> str: ... + @classmethod @abstractmethod - def is_saveable(self, filename: str) -> bool: - ... + def input_extensions(cls) -> list[str]: ... + @classmethod @abstractmethod - def save(self, filename: str) -> list[str]: - ... + def object_priority(cls, filename: str) -> int: ... + @classmethod @abstractmethod - def save_viewable(self, filename_without_extension: str) -> str: - ... + def output_extensions(cls) -> list[str]: ... @abstractmethod - def save_light_viewable(self, filename_without_extension: str) -> str: - ... + def is_saveable(self, filename: str) -> bool: ... + @abstractmethod + def save(self, filename: str) -> list[str]: ... -geode_objects: dict[GeodeType, type[GeodeObject]] = {"BRep": GeodeBRep} + @abstractmethod + def save_viewable(self, filename_without_extension: str) -> str: ... + @abstractmethod + def save_light_viewable(self, filename_without_extension: str) -> str: ... mesh = "mesh" @@ -101,7 +101,6 @@ def save_light_viewable(self, filename_without_extension: str) -> str: polyhedrons = "polyhedrons" - # def geode_objects_dict(): # return { # "BRep": { diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index f44788f5..8dab4d48 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -45,9 +45,6 @@ def allowed_files() -> flask.Response: methods=schemas_dict["upload_file"]["methods"], ) def upload_file() -> flask.Response: - if flask.request.method == "OPTIONS": - return flask.make_response({}, 200) - UPLOAD_FOLDER = flask.current_app.config["UPLOAD_FOLDER"] if not os.path.exists(UPLOAD_FOLDER): os.makedirs(UPLOAD_FOLDER, exist_ok=True) @@ -63,9 +60,6 @@ def upload_file() -> flask.Response: methods=schemas_dict["allowed_objects"]["methods"], ) def allowed_objects() -> flask.Response: - if flask.request.method == "OPTIONS": - return flask.make_response({}, 200) - utils_functions.validate_request(flask.request, schemas_dict["allowed_objects"]) params = schemas.AllowedObjects.from_dict(flask.request.get_json()) file_absolute_path = geode_functions.upload_file_path(params.filename) @@ -75,6 +69,26 @@ def allowed_objects() -> flask.Response: return flask.make_response({"allowed_objects": allowed_objects}, 200) +# def list_geode_objects( +# file_absolute_path: str, +# key: str | None = None, +# ): +# return_dict = {} +# file_extension = utils_functions.extension_from_filename( +# os.path.basename(file_absolute_path) +# ) +# geode_objects_filtered_list = filter_geode_objects(key) +# for geode_object in geode_objects_filtered_list: +# if has_creator(geode_object, file_extension): +# loadability_score = is_loadable(geode_object, file_absolute_path) +# priority_score = object_priority(geode_object, file_absolute_path) +# return_dict[geode_object] = { +# "is_loadable": loadability_score, +# "object_priority": priority_score, +# } +# return return_dict + + @routes.route( schemas_dict["missing_files"]["route"], methods=schemas_dict["missing_files"]["methods"], @@ -136,6 +150,13 @@ def crs_converter_geographic_coordinate_systems() -> flask.Response: return flask.make_response({"crs_list": crs_list}, 200) +# def geographic_coordinate_systems(geode_type: GeodeType): +# if is_3D(geode_object): +# return og_gs.GeographicCoordinateSystem3D.geographic_coordinate_systems() +# else: +# return og_gs.GeographicCoordinateSystem2D.geographic_coordinate_systems() + + @routes.route( schemas_dict["inspect_file"]["route"], methods=schemas_dict["inspect_file"]["methods"], @@ -150,6 +171,32 @@ def inspect_file() -> flask.Response: return flask.make_response({"inspection_result": inspection_result}, 200) +# def get_inspector_children(obj): +# new_object = {} + +# if "inspection_type" in dir(obj): +# new_object["title"] = obj.inspection_type() +# new_object["nb_issues"] = 0 +# new_object["children"] = [] +# for child in dir(obj): +# if not child.startswith("__") and not child in [ +# "inspection_type", +# "string", +# ]: +# child_instance = obj.__getattribute__(child) +# child_object = get_inspector_children(child_instance) +# new_object["children"].append(child_object) +# new_object["nb_issues"] += child_object["nb_issues"] +# else: +# new_object["title"] = obj.description() +# nb_issues = obj.nb_issues() +# new_object["nb_issues"] = nb_issues +# if nb_issues > 0: +# issues = obj.string().split("\n") +# new_object["issues"] = issues +# return new_object + + @routes.route( schemas_dict["geode_objects_and_output_extensions"]["route"], methods=schemas_dict["geode_objects_and_output_extensions"]["methods"], @@ -173,6 +220,23 @@ def geode_objects_and_output_extensions() -> flask.Response: ) +# def geode_objects_output_extensions(geode_type: GeodeType, data): +# geode_objects_output_extensions_dict = {} +# output_extensions = geode_object_output_extensions(geode_object) +# extensions_dict = {} +# for output_extension in output_extensions: +# bool_is_saveable = is_saveable(geode_object, data, f"test.{output_extension}") +# extensions_dict[output_extension] = {"is_saveable": bool_is_saveable} +# geode_objects_output_extensions_dict[geode_object] = extensions_dict + +# if "parent" in geode_objects[geode_type].keys(): +# parent_geode_object = geode_objects[geode_type]["parent"] +# geode_objects_output_extensions_dict.update( +# geode_objects_output_extensions(parent_geode_object, data) +# ) +# return geode_objects_output_extensions_dict + + @routes.route( schemas_dict["save_viewable_file"]["route"], methods=schemas_dict["save_viewable_file"]["methods"], diff --git a/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py b/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py index f9eb3550..888178c5 100644 --- a/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py +++ b/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py @@ -8,4 +8,4 @@ def __post_init__(self) -> None: print(self, flush=True) filename: str - input_geode_type: GeodeType + input_geode_object: str diff --git a/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py b/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py index 67415c28..31353997 100644 --- a/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py +++ b/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py @@ -7,4 +7,4 @@ class GeographicCoordinateSystems(DataClassJsonMixin): def __post_init__(self) -> None: print(self, flush=True) - input_geode_type: GeodeType + input_geode_object: str diff --git a/src/opengeodeweb_back/routes/schemas/inspect_file.py b/src/opengeodeweb_back/routes/schemas/inspect_file.py index 46fcac0f..0e0e36ea 100644 --- a/src/opengeodeweb_back/routes/schemas/inspect_file.py +++ b/src/opengeodeweb_back/routes/schemas/inspect_file.py @@ -8,4 +8,4 @@ def __post_init__(self) -> None: print(self, flush=True) filename: str - input_geode_type: GeodeType + input_geode_object: str diff --git a/src/opengeodeweb_back/routes/schemas/missing_files.py b/src/opengeodeweb_back/routes/schemas/missing_files.py index 822df519..05a99f0a 100644 --- a/src/opengeodeweb_back/routes/schemas/missing_files.py +++ b/src/opengeodeweb_back/routes/schemas/missing_files.py @@ -8,4 +8,4 @@ def __post_init__(self) -> None: print(self, flush=True) filename: str - input_geode_type: GeodeType + input_geode_object: str diff --git a/src/opengeodeweb_back/routes/schemas/save_viewable_file.py b/src/opengeodeweb_back/routes/schemas/save_viewable_file.py index 29198a73..754e5b32 100644 --- a/src/opengeodeweb_back/routes/schemas/save_viewable_file.py +++ b/src/opengeodeweb_back/routes/schemas/save_viewable_file.py @@ -8,4 +8,4 @@ def __post_init__(self) -> None: print(self, flush=True) filename: str - input_geode_type: GeodeType + input_geode_object: str diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index 0f465a22..ba05e750 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -13,13 +13,15 @@ import shutil from werkzeug.exceptions import HTTPException import werkzeug - -# Local application imports -from . import geode_functions from opengeodeweb_microservice.schemas import SchemaDict from opengeodeweb_microservice.database.data import Data from opengeodeweb_microservice.database.connection import get_session +# Local application imports +from . import geode_functions +from .geode_objects import geode_objects +from .geode_objects.geode_object import GeodeType, GeodeObject + def increment_request_counter(current_app: flask.Flask) -> None: if "REQUEST_COUNTER" in current_app.config: @@ -158,15 +160,14 @@ def send_file( def handle_exception(exception: HTTPException) -> flask.Response: - response = exception.get_response() - response.data = flask.json.dumps( + response = flask.jsonify( { "code": exception.code, "name": exception.name, - "description": exception.description, + "description": exception.description or "An error occurred", } ) - response.content_type = "application/json" + response.status_code = exception.code or 500 return response @@ -178,72 +179,65 @@ def create_data_folder_from_id(data_id: str) -> str: def save_all_viewables_and_return_info( - geode_type: GeodeType, - data: object, - data_entry: Data, + geode_object: GeodeObject, + data: Data, data_path: str, ) -> dict[str, str | list[str]]: with ThreadPoolExecutor() as executor: native_future = executor.submit( - geode_functions.save, - geode_object, - data, - data_path, - "native." + data.native_extension(), + geode_object.save, + os.path.join(data_path, "native." + geode_object.native_extension()), ) viewable_future = executor.submit( - geode_functions.save_viewable, geode_object, data, data_path, "viewable" + geode_object.save_viewable, os.path.join(data_path, "viewable") ) light_viewable_future = executor.submit( - geode_functions.save_light_viewable, - geode_object, - data, - data_path, - "light_viewable", + geode_object.save_light_viewable, os.path.join(data_path, "light_viewable") ) saved_light_viewable_file_path = light_viewable_future.result() with open(saved_light_viewable_file_path, "rb") as f: binary_light_viewable = f.read() saved_native_file_path = native_future.result() saved_viewable_file_path = viewable_future.result() - data_entry.native_file_name = os.path.basename(saved_native_file_path[0]) - data_entry.viewable_file_name = os.path.basename(saved_viewable_file_path) - data_entry.light_viewable = os.path.basename(saved_light_viewable_file_path) + data.native_file_name = os.path.basename(saved_native_file_path[0]) + data.viewable_file_name = os.path.basename(saved_viewable_file_path) + data.light_viewable = os.path.basename(saved_light_viewable_file_path) return { - "native_file_name": data_entry.native_file_name, - "viewable_file_name": data_entry.viewable_file_name, - "id": data_entry.id, - "name": data.name(), # type: ignore - "object_type": geode_functions.get_object_type(geode_object), + "native_file_name": data.native_file_name, + "viewable_file_name": data.viewable_file_name, + "id": data.id, + "name": geode_object.identifier.name(), + "viewer_type": data.viewer_object, "binary_light_viewable": binary_light_viewable.decode("utf-8"), - "geode_object": data_entry.geode_object, - "input_file": data_entry.input_file, - "additional_files": data_entry.additional_files, + "geode_type": data.geode_object, + "input_file": data.input_file or "", + "additional_files": data.additional_files or [], } def generate_native_viewable_and_light_viewable_from_object( - geode_type: GeodeType, data: object + geode_object: GeodeObject, ) -> dict[str, str | list[str]]: - data_entry = Data.create( - geode_object=geode_object, - viewer_object=geode_functions.get_object_type(geode_object), + data = Data.create( + geode_object=geode_object.geode_type(), + viewer_object=geode_object.viewer_type(), ) - data_path = create_data_folder_from_id(data_entry.id) - return save_all_viewables_and_return_info(geode_object, data, data_entry, data_path) + data_path = create_data_folder_from_id(data.id) + return save_all_viewables_and_return_info(geode_object, data, data_path) def generate_native_viewable_and_light_viewable_from_file( geode_type: GeodeType, input_filename: str ) -> dict[str, str | list[str]]: - data_entry = Data.create( - geode_object=geode_object, - viewer_object=geode_functions.get_object_type(geode_object), + generic_geode_object = geode_objects[geode_type] + data = Data.create( + geode_object=geode_type, + viewer_object=generic_geode_object.viewer_type(), input_file=input_filename, ) - data_path = create_data_folder_from_id(data_entry.id) + data_path = create_data_folder_from_id(data.id) full_input_filename = geode_functions.upload_file_path(input_filename) copied_full_path = os.path.join( @@ -252,7 +246,7 @@ def generate_native_viewable_and_light_viewable_from_file( shutil.copy2(full_input_filename, copied_full_path) additional_files_copied: list[str] = [] - additional = geode_functions.additional_files(geode_object, full_input_filename) + additional = generic_geode_object.additional_files(full_input_filename) for additional_file in additional.mandatory_files + additional.optional_files: if additional_file.is_missing: continue @@ -266,12 +260,10 @@ def generate_native_viewable_and_light_viewable_from_file( shutil.copy2(source_path, dest_path) additional_files_copied.append(additional_file.filename) - data = geode_functions.load(geode_object, copied_full_path) - - data_entry.additional_files = additional_files_copied + geode_object = generic_geode_object.load(copied_full_path) + data.additional_files = additional_files_copied return save_all_viewables_and_return_info( geode_object, data, - data_entry, data_path, ) diff --git a/tests/conftest.py b/tests/conftest.py index 283d2188..f9815593 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,6 +6,8 @@ from typing import Generator # Third party imports +from flask.ctx import AppContext +from flask.testing import FlaskClient import pytest # Local application imports @@ -47,20 +49,20 @@ def configure_test_environment() -> Generator[None, None, None]: @pytest.fixture -def client(): +def client() -> Generator[FlaskClient, None, None]: app.config["REQUEST_COUNTER"] = 0 app.config["LAST_REQUEST_TIME"] = time.time() client = app.test_client() - client.headers = {"Content-type": "application/json", "Accept": "application/json"} + # client.headers = {"Content-type": "application/json", "Accept": "application/json"} yield client @pytest.fixture -def app_context(): - with app.app_context(): - yield +def app_context() -> Generator[AppContext, None, None]: + with app.app_context() as ctx: + yield ctx @pytest.fixture -def test_id(): +def test_id() -> str: return TEST_ID diff --git a/tests/test_geode_functions.py b/tests/test_geode_functions.py index b3c57b1c..b407497c 100644 --- a/tests/test_geode_functions.py +++ b/tests/test_geode_functions.py @@ -1,337 +1,65 @@ # Standard library imports import os import uuid +from typing import get_args # Third party imports # Local application imports -from opengeodeweb_back import geode_functions, geode_objects +from opengeodeweb_back import geode_functions +from opengeodeweb_back.geode_objects import geode_objects +from opengeodeweb_back.geode_objects.geode_object import GeodeType data_folder = os.path.join(os.path.dirname(__file__), "data") -def test_geode_object_value(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - geode_object_value = geode_functions.geode_object_value(geode_object) - assert type(geode_object_value) is dict +def test_geode_objects() -> None: + for geode_type in get_args(GeodeType): + assert geode_type in geode_objects -def test_input_factory(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - geode_object_input = geode_functions.input_factory(geode_object) - assert type(geode_object_input.list_creators()) is list - - -def test_input_extensions(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - geode_object_input_extensions = geode_functions.geode_object_input_extensions( - geode_object - ) - - assert type(geode_object_input_extensions) is list - for extension in geode_object_input_extensions: - assert type(extension) is str - - -def test_output_factory(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - geode_object_output = geode_functions.output_factory(geode_object) - geode_object_output_list = geode_object_output.list_creators() - assert type(geode_object_output_list) is list - for output in geode_object_output_list: - assert type(output) is str - - -def test_additional_files(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - input_extensions = geode_functions.geode_object_input_extensions(geode_object) - for input_extension in input_extensions: - file_absolute_path = os.path.join(data_folder, f"test.{input_extension}") - additional_files = geode_functions.additional_files( - geode_object, file_absolute_path - ) - mandatory_files = additional_files.mandatory_files - optional_files = additional_files.optional_files - assert type(mandatory_files) is list - assert type(optional_files) is list - - -def test_is_loadable(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - input_extensions = geode_functions.geode_object_input_extensions(geode_object) - for input_extension in input_extensions: - file_absolute_path = os.path.join(data_folder, f"test.{input_extension}") - is_loadable = geode_functions.is_loadable(geode_object, file_absolute_path) - assert isinstance(is_loadable, float) - assert 0.0 <= is_loadable <= 1.0 - - -def test_object_priority(): - for geode_object, _value in geode_objects.geode_objects_dict().items(): - input_extensions = geode_functions.geode_object_input_extensions(geode_object) - for input_extension in input_extensions: - file_absolute_path = os.path.join(data_folder, f"test.{input_extension}") - priority = geode_functions.object_priority(geode_object, file_absolute_path) - assert isinstance( - priority, int - ), f"Priority should be int for {geode_object}" - - -def test_load(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - print(f"\n{geode_object=}") - input_extensions = geode_functions.geode_object_input_extensions(geode_object) - for input_extension in input_extensions: +def test_input_output() -> None: + for generic_geode_object in geode_objects.values(): + print(f"\n{generic_geode_object.geode_type()=}") + for input_extension in generic_geode_object.input_extensions(): print(f"\t{input_extension=}") file_absolute_path = os.path.join(data_folder, f"test.{input_extension}") - if geode_functions.is_loadable(geode_object, file_absolute_path) > 0.0: - data = geode_functions.load(geode_object, file_absolute_path) - data_name = data.name() - if "save_viewable" in value: - viewable_file_path = geode_functions.save_viewable( - geode_object, - data, - os.path.abspath(f"./output"), - data_name, - ) - os.remove(viewable_file_path) - - if "save_light_viewable" in value: - light_viewable_file_path = geode_functions.save_light_viewable( - geode_object, - data, - os.path.abspath(f"./output"), - data_name, - ) - os.remove(light_viewable_file_path) - geode_objects_and_output_extensions = ( - geode_functions.geode_objects_output_extensions(geode_object, data) + if generic_geode_object.is_loadable(file_absolute_path).value() == 0.0: + continue + geode_object = generic_geode_object.load(file_absolute_path) + data_name = geode_object.identifier.name() + if geode_object.is_viewable(): + viewable_file_path = geode_object.save_viewable( + os.path.join(os.path.abspath(f"./output"), data_name) ) - assert type(geode_objects_and_output_extensions) is dict - for ( - output_geode_object, - output_geode_object_value, - ) in geode_objects_and_output_extensions.items(): - print(f"\t\t{output_geode_object=}") - for ( - output_extension, - output_extension_value, - ) in output_geode_object_value.items(): - print(f"\t\t\t{output_extension=}") - uu_id = str(uuid.uuid4()).replace("-", "") - filename = f"{uu_id}.{output_extension}" - if geode_functions.is_saveable( - output_geode_object, data, filename - ): - saved_files = geode_functions.save( - output_geode_object, - data, - os.path.abspath(f"./output"), - filename, - ) - assert type(saved_files) is list - for saved_file in saved_files: - os.remove(saved_file) - - -def test_get_object_type(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - object_type = geode_functions.get_object_type(geode_object) - assert type(object_type) is str - assert object_type in ["model", "mesh"] - - -def test_is_3D(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - is_3D = geode_functions.is_3D(geode_object) - assert type(is_3D) is bool - - -def test_is_viewable(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - is_viewable = geode_functions.is_viewable(geode_object) - assert type(is_viewable) is bool - - -def test_geode_object_input_extensions(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - input_extensions = geode_functions.geode_object_input_extensions(geode_object) - assert type(input_extensions) is list - for input_extension in input_extensions: - assert type(input_extension) is str - - -def test_geode_object_output_extensions(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - print(f"\n{geode_object=}") - input_extensions = geode_functions.geode_object_input_extensions(geode_object) - for input_extension in input_extensions: - print(f"\t{input_extension=}") - file_absolute_path = os.path.join(data_folder, f"test.{input_extension}") - additional = geode_functions.additional_files( - geode_object, file_absolute_path - ) - has_missing_files = any( - f.is_missing - for f in additional.mandatory_files + additional.optional_files - ) - if has_missing_files: - print( - f"\t\tMandatory files: {[f.filename for f in additional.mandatory_files]}" + os.remove(viewable_file_path) + if geode_object.is_viewable(): + light_viewable_file_path = geode_object.save_light_viewable( + os.path.join(os.path.abspath(f"./output"), data_name) ) - print( - f"\t\tAdditional files: {[f.filename for f in additional.optional_files]}" - ) - if geode_functions.is_loadable(geode_object, file_absolute_path) > 0.0: - data = geode_functions.load(geode_object, file_absolute_path) - geode_objets_and_output_extensions = ( - geode_functions.geode_objects_output_extensions(geode_object, data) - ) - data_name = data.name() - assert isinstance(geode_objets_and_output_extensions, dict) - for ( - output_geode_object, - output_geode_object_value, - ) in geode_objets_and_output_extensions.items(): - for ( - output_extension, - output_extension_value, - ) in output_geode_object_value.items(): - assert isinstance(output_extension, str) - assert isinstance(output_extension_value["is_saveable"], bool) - - -def test_get_inspector_children(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - if "inspector" in value: - print(f"\n{geode_object=}", flush=True) - input_extensions = geode_functions.geode_object_input_extensions( - geode_object + os.remove(light_viewable_file_path) + geode_objects_output_extensions = ( + geode_functions.geode_object_output_extensions(geode_object) ) - for input_extension in input_extensions: - print(f"\t{input_extension=}", flush=True) - file_absolute_path = os.path.join( - data_folder, f"test.{input_extension}" - ) - additional = geode_functions.additional_files( - geode_object, file_absolute_path - ) - has_missing_files = any( - f.is_missing - for f in additional.mandatory_files + additional.optional_files - ) - if has_missing_files: - mandatory_files = [f.filename for f in additional.mandatory_files] - print(f"\t\t{mandatory_files=}", flush=True) - additional_files = [f.filename for f in additional.optional_files] - print(f"\t\t{additional_files=}", flush=True) - if geode_functions.is_loadable(geode_object, file_absolute_path) > 0.0: - data = geode_functions.load(geode_object, file_absolute_path) - class_inspector = geode_functions.inspect(geode_object, data) - assert "InspectionResult" in class_inspector.__class__.__name__ - inspection_result = geode_functions.get_inspector_children( - class_inspector - ) - - print(f"\t\t{inspection_result=}", flush=True) - assert isinstance(inspection_result, dict) - - -def test_filter_geode_objects(): - filters_list = ["", "crs", "inspector", None] - - for filter in filters_list: - geode_objects_filtered_list = geode_functions.filter_geode_objects(filter) - assert type(geode_objects_filtered_list) is list - for geode_object in geode_objects_filtered_list: - assert type(geode_object) is str - - -def test_list_input_extensions(): - keys_array = ["crs", "inspector", None] - for geode_object, value in geode_objects.geode_objects_dict().items(): - for keys in keys_array: - input_extensions = geode_functions.list_input_extensions(keys) - assert type(input_extensions) is list - - -def test_list_geode_objects(): - test_list = [ - { - "key": "crs", - "invalid_geode_objects": [ - "Graph", - "RasterImage2D", - "RasterImage3D", - "VertexSet", - ], - }, - { - "key": "inspector", - "invalid_geode_objects": [ - "Graph", - "RasterImage2D", - "RasterImage3D", - "VertexSet", - ], - }, - { - "key": None, - "invalid_geode_objects": [], - }, - ] - for test in test_list: - key = test["key"] - invalid_geode_objects = test["invalid_geode_objects"] - - input_extensions = geode_functions.list_input_extensions(key) - for geode_object, value in geode_objects.geode_objects_dict().items(): - for input_extension in input_extensions: - file_absolute_path = os.path.join( - data_folder, f"test.{input_extension}" - ) - return_dict = geode_functions.list_geode_objects( - file_absolute_path, key - ) - assert type(return_dict) is dict - - if key != None: - assert len(return_dict.keys()) > 0 - for invalid_geode_object in invalid_geode_objects: - assert invalid_geode_object not in return_dict.keys() - else: - assert len(return_dict.keys()) >= 1 - for input_geode_object, input_extension_dict in return_dict.items(): - assert type(input_extension_dict) is dict - if "is_loadable" in input_extension_dict: - is_loadable_value = input_extension_dict["is_loadable"] - assert isinstance(is_loadable_value, float) - assert 0.0 <= is_loadable_value <= 1.0 - assert "object_priority" in input_extension_dict - object_priority_value = input_extension_dict[ - "object_priority" - ] - assert isinstance(object_priority_value, int) - - -def test_geode_objects_output_extensions(): - for geode_object, value in geode_objects.geode_objects_dict().items(): - input_extensions = geode_functions.geode_object_input_extensions(geode_object) - for input_extension in input_extensions: - file_absolute_path = os.path.join(data_folder, f"test.{input_extension}") - if geode_functions.is_loadable(geode_object, file_absolute_path) > 0.0: - data = geode_functions.load(geode_object, file_absolute_path) - geode_objects_and_output_extensions = ( - geode_functions.geode_objects_output_extensions(geode_object, data) - ) - assert type(geode_objects_and_output_extensions) is dict + assert type(geode_objects_output_extensions) is dict + for ( + output_geode_type, + output_geode_extensions, + ) in geode_objects_output_extensions.items(): + print(f"\t\t{output_geode_type=}") for ( - output_geode_object, - output_geode_object_value, - ) in geode_objects_and_output_extensions.items(): - for ( - output_extension, - output_extension_value, - ) in output_geode_object_value.items(): - assert type(output_extension_value["is_saveable"]) is bool + output_extension, + output_is_saveable, + ) in output_geode_extensions.items(): + print(f"\t\t\t{output_extension=}") + uu_id = str(uuid.uuid4()).replace("-", "") + filename = f"{uu_id}.{output_extension}" + if output_is_saveable: + saved_files = geode_objects[output_geode_type].save( + geode_object, + os.path.join(os.path.abspath(f"./output"), filename), + ) + assert type(saved_files) is list + for saved_file in saved_files: + os.remove(saved_file) diff --git a/tests/test_routes.py b/tests/test_routes.py index bd8220e5..79eda492 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -3,6 +3,7 @@ # Third party imports from werkzeug.datastructures import FileStorage +from flask.testing import FlaskClient # Local application imports from opengeodeweb_microservice.database.data import Data @@ -13,7 +14,7 @@ data_dir = os.path.join(base_dir, "data") -def test_allowed_files(client): +def test_allowed_files(client: FlaskClient) -> None: route = f"/opengeodeweb_back/allowed_files" get_full_data = lambda: {"supported_feature": "None"} json = get_full_data() @@ -28,7 +29,7 @@ def test_allowed_files(client): test_utils.test_route_wrong_params(client, route, get_full_data) -def test_allowed_objects(client): +def test_allowed_objects(client: FlaskClient) -> None: route = f"/opengeodeweb_back/allowed_objects" def get_full_data(): @@ -59,7 +60,7 @@ def test_upload_file(client, filename="test.og_brep"): assert response.status_code == 201 -def test_missing_files(client): +def test_missing_files(client: FlaskClient) -> None: route = f"/opengeodeweb_back/missing_files" def get_full_data(): @@ -82,7 +83,7 @@ def get_full_data(): test_utils.test_route_wrong_params(client, route, get_full_data) -def test_geographic_coordinate_systems(client): +def test_geographic_coordinate_systems(client: FlaskClient) -> None: route = f"/opengeodeweb_back/geographic_coordinate_systems" get_full_data = lambda: {"input_geode_object": "BRep"} # Normal test with geode_object 'BRep' @@ -97,7 +98,7 @@ def test_geographic_coordinate_systems(client): test_utils.test_route_wrong_params(client, route, get_full_data) -def test_inspect_file(client): +def test_inspect_file(client: FlaskClient) -> None: route = f"/opengeodeweb_back/inspect_file" def get_full_data(): @@ -118,7 +119,7 @@ def get_full_data(): test_utils.test_route_wrong_params(client, route, get_full_data) -def test_geode_objects_and_output_extensions(client): +def test_geode_objects_and_output_extensions(client: FlaskClient) -> None: route = "/opengeodeweb_back/geode_objects_and_output_extensions" def get_full_data(): @@ -144,7 +145,7 @@ def get_full_data(): test_utils.test_route_wrong_params(client, route, get_full_data) -def test_save_viewable_file(client): +def test_save_viewable_file(client: FlaskClient) -> None: test_upload_file(client, filename="corbi.og_brep") route = f"/opengeodeweb_back/save_viewable_file" @@ -278,7 +279,7 @@ def test_polyhedron_attribute_names(client, test_id): assert type(polyhedron_attribute_name) is str -def test_database_uri_path(client): +def test_database_uri_path(client: FlaskClient) -> None: app = client.application with app.app_context(): base_dir = os.path.abspath(os.path.dirname(__file__)) diff --git a/tests/test_utils_functions.py b/tests/test_utils_functions.py index ea75794b..8de1e09a 100644 --- a/tests/test_utils_functions.py +++ b/tests/test_utils_functions.py @@ -4,53 +4,58 @@ # Third party imports import flask +from flask.ctx import AppContext +from flask.testing import FlaskClient import shutil import uuid import zipfile import io +from pathlib import Path # Local application imports from opengeodeweb_microservice.database.data import Data from opengeodeweb_microservice.database.connection import get_session from opengeodeweb_back import geode_functions, utils_functions +from opengeodeweb_back.geode_objects.geode_object import to_geode_type +from opengeodeweb_back.geode_objects.geode_brep import GeodeBRep base_dir = os.path.abspath(os.path.dirname(__file__)) data_dir = os.path.join(base_dir, "data") -def test_increment_request_counter(app_context): +def test_increment_request_counter(app_context: AppContext) -> None: assert flask.current_app.config.get("REQUEST_COUNTER") == 0 utils_functions.increment_request_counter(flask.current_app) assert flask.current_app.config.get("REQUEST_COUNTER") == 1 -def test_decrement_request_counter(app_context): +def test_decrement_request_counter(app_context: AppContext) -> None: assert flask.current_app.config.get("REQUEST_COUNTER") == 1 utils_functions.decrement_request_counter(flask.current_app) assert flask.current_app.config.get("REQUEST_COUNTER") == 0 -def test_update_last_request_time(app_context): +def test_update_last_request_time(app_context: AppContext) -> None: LAST_REQUEST_TIME = flask.current_app.config.get("LAST_REQUEST_TIME") utils_functions.update_last_request_time(flask.current_app) - assert flask.current_app.config.get("LAST_REQUEST_TIME") >= LAST_REQUEST_TIME + assert flask.current_app.config.get("LAST_REQUEST_TIME", 0) >= LAST_REQUEST_TIME -def test_before_request(app_context): +def test_before_request(app_context: AppContext) -> None: assert flask.current_app.config.get("REQUEST_COUNTER") == 0 utils_functions.before_request(flask.current_app) assert flask.current_app.config.get("REQUEST_COUNTER") == 1 -def test_teardown_request(app_context): +def test_teardown_request(app_context: AppContext) -> None: LAST_REQUEST_TIME = flask.current_app.config.get("LAST_REQUEST_TIME") assert flask.current_app.config.get("REQUEST_COUNTER") == 1 utils_functions.teardown_request(flask.current_app) assert flask.current_app.config.get("REQUEST_COUNTER") == 0 - assert flask.current_app.config.get("LAST_REQUEST_TIME") >= LAST_REQUEST_TIME + assert flask.current_app.config.get("LAST_REQUEST_TIME", 0) >= LAST_REQUEST_TIME -def test_versions(): +def test_versions() -> None: list_packages = [ "OpenGeode-core", "OpenGeode-IO", @@ -63,13 +68,13 @@ def test_versions(): assert type(version) is dict -def test_extension_from_filename(): +def test_extension_from_filename() -> None: extension = utils_functions.extension_from_filename("test.toto") assert type(extension) is str assert extension.count(".") == 0 -def test_handle_exception(client): +def test_handle_exception(client: FlaskClient) -> None: route = "/error" response = client.post(route) assert response.status_code == 500 @@ -80,7 +85,7 @@ def test_handle_exception(client): assert type(data["code"]) is int -def test_create_data_folder_from_id(client): +def test_create_data_folder_from_id(client: FlaskClient) -> None: app = client.application with app.app_context(): test_id = str(uuid.uuid4()).replace("-", "") @@ -93,7 +98,7 @@ def test_create_data_folder_from_id(client): assert not os.path.exists(data_path) -def test_save_all_viewables_and_return_info(client): +def test_save_all_viewables_and_return_info(client: FlaskClient) -> None: app = client.application with app.app_context(): expected_db_path = os.path.join(data_dir, "project.db") @@ -102,41 +107,42 @@ def test_save_all_viewables_and_return_info(client): assert app.config["SQLALCHEMY_DATABASE_URI"] == expected_uri assert os.path.exists(expected_db_path) - geode_object = "BRep" - data = geode_functions.load( - geode_object, os.path.join(data_dir, "test.og_brep") - ) + geode_object = GeodeBRep.load(os.path.join(data_dir, "test.og_brep")) input_file = "test.og_brep" additional_files = ["additional_file.txt"] data_entry = Data.create( - geode_object=geode_object, - viewer_object=geode_functions.get_object_type(geode_object), + geode_object=geode_object.geode_type(), + viewer_object=geode_object.viewer_type(), input_file=input_file, additional_files=additional_files, ) data_path = utils_functions.create_data_folder_from_id(data_entry.id) result = utils_functions.save_all_viewables_and_return_info( - geode_object, data, data_entry, data_path + geode_object, data_entry, data_path ) assert isinstance(result, dict) - assert result["native_file_name"].startswith("native.") - assert result["viewable_file_name"].endswith(".vtm") + native_file_name = result["native_file_name"] + assert isinstance(native_file_name, str) + assert native_file_name.startswith("native.") + viewable_file_name = result["viewable_file_name"] + assert isinstance(viewable_file_name, str) + assert viewable_file_name.endswith(".vtm") assert isinstance(result["id"], str) assert len(result["id"]) == 32 assert re.match(r"[0-9a-f]{32}", result["id"]) - assert isinstance(result["object_type"], str) + assert isinstance(result["viewer_type"], str) assert isinstance(result["binary_light_viewable"], str) - assert result["geode_object"] == geode_object + assert result["geode_type"] == geode_object.geode_type() assert result["input_file"] == input_file db_entry = Data.get(result["id"]) assert db_entry is not None assert db_entry.native_file_name == result["native_file_name"] assert db_entry.viewable_file_name == result["viewable_file_name"] - assert db_entry.geode_object == geode_object + assert db_entry.geode_object == geode_object.geode_type() assert db_entry.input_file == input_file assert db_entry.additional_files == additional_files @@ -144,43 +150,39 @@ def test_save_all_viewables_and_return_info(client): assert os.path.exists(expected_data_path) -def test_save_all_viewables_commits_to_db(client): +def test_save_all_viewables_commits_to_db(client: FlaskClient) -> None: app = client.application with app.app_context(): - geode_object = "BRep" - data = geode_functions.load( - geode_object, os.path.join(data_dir, "test.og_brep") - ) + geode_object = GeodeBRep.load(os.path.join(data_dir, "test.og_brep")) input_file = "test.og_brep" - data_entry = Data.create( - geode_object=geode_object, - viewer_object=geode_functions.get_object_type(geode_object), + geode_object=geode_object.geode_type(), + viewer_object=geode_object.viewer_type(), input_file=input_file, additional_files=[], ) data_path = utils_functions.create_data_folder_from_id(data_entry.id) result = utils_functions.save_all_viewables_and_return_info( - geode_object, data, data_entry, data_path + geode_object, data_entry, data_path ) data_id = result["id"] + assert isinstance(data_id, str) db_entry_before = Data.get(data_id) assert db_entry_before is not None assert db_entry_before.native_file_name == result["native_file_name"] -def test_generate_native_viewable_and_light_viewable_from_object(client): +def test_generate_native_viewable_and_light_viewable_from_object( + client: FlaskClient, +) -> None: app = client.application with app.app_context(): - geode_object = "BRep" - data = geode_functions.load( - geode_object, os.path.join(data_dir, "test.og_brep") - ) + geode_object = GeodeBRep.load(os.path.join(data_dir, "test.og_brep")) result = ( utils_functions.generate_native_viewable_and_light_viewable_from_object( - geode_object, data + geode_object ) ) @@ -191,19 +193,20 @@ def test_generate_native_viewable_and_light_viewable_from_object(client): assert result["viewable_file_name"].endswith(".vtm") assert isinstance(result["id"], str) assert re.match(r"[0-9a-f]{32}", result["id"]) - assert isinstance(result["object_type"], str) + assert isinstance(result["viewer_type"], str) assert isinstance(result["binary_light_viewable"], str) - assert result["input_file"] == None + assert result["input_file"] == "" -def test_generate_native_viewable_and_light_viewable_from_file(client): +def test_generate_native_viewable_and_light_viewable_from_file( + client: FlaskClient, +) -> None: app = client.application with app.app_context(): - geode_object = "BRep" + geode_type = to_geode_type("BRep") input_filename = "test.og_brep" - result = utils_functions.generate_native_viewable_and_light_viewable_from_file( - geode_object, input_filename + geode_type, input_filename ) assert isinstance(result, dict) @@ -213,12 +216,12 @@ def test_generate_native_viewable_and_light_viewable_from_file(client): assert result["viewable_file_name"].endswith(".vtm") assert isinstance(result["id"], str) assert re.match(r"[0-9a-f]{32}", result["id"]) - assert isinstance(result["object_type"], str) + assert isinstance(result["viewer_type"], str) assert isinstance(result["binary_light_viewable"], str) assert isinstance(result["input_file"], str) -def test_send_file_multiple_returns_zip(client, tmp_path): +def test_send_file_multiple_returns_zip(client: FlaskClient, tmp_path: Path) -> None: app = client.application with app.app_context(): app.config["UPLOAD_FOLDER"] = str(tmp_path) @@ -243,7 +246,9 @@ def test_send_file_multiple_returns_zip(client, tmp_path): response.close() -def test_send_file_single_returns_octet_binary(client, tmp_path): +def test_send_file_single_returns_octet_binary( + client: FlaskClient, tmp_path: Path +) -> None: app = client.application with app.app_context(): app.config["UPLOAD_FOLDER"] = str(tmp_path) From 31554d5cf206634f2398e421bf2b01a2e909137e Mon Sep 17 00:00:00 2001 From: BotellaA <3213882+BotellaA@users.noreply.github.com> Date: Tue, 18 Nov 2025 15:04:50 +0000 Subject: [PATCH 03/21] Apply prepare changes --- commitlint.config.js | 5 ++++- requirements.txt | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/commitlint.config.js b/commitlint.config.js index 3a29484e..a397334b 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -1,4 +1,4 @@ -export default { +const Configuration = { extends: ["@commitlint/config-angular"], rules: { "scope-empty": [2, "never"], @@ -12,5 +12,8 @@ export default { "subject-full-stop": [0], "type-case": [0], "type-empty": [0], + "type-enum": [2, "always", ["feat", "fix", "perf"]], }, } + +export default Configuration diff --git a/requirements.txt b/requirements.txt index 0d6a8e5a..78173de7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -60,4 +60,3 @@ werkzeug==3.1.2 # flask # flask-cors -opengeodeweb-microservice==1.*,>=1.0.9rc2 From ad1479dc2547d2fc4b001bcd3f078af13d889b0c Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 19 Nov 2025 11:24:17 +0100 Subject: [PATCH 04/21] wip --- opengeodeweb_back_schemas.json | 42 ++-- src/opengeodeweb_back/app.py | 1 + src/opengeodeweb_back/geode_functions.py | 100 ++++++--- .../geode_objects/__init__.py | 13 +- .../geode_objects/geode_brep.py | 25 ++- .../geode_objects/geode_mesh.py | 33 +++ .../geode_objects/geode_model.py | 38 ++++ .../geode_objects/geode_object.py | 24 +-- src/opengeodeweb_back/geode_objects/types.py | 51 +++++ .../routes/blueprint_routes.py | 189 ++++++++---------- .../routes/create/blueprint_create.py | 2 +- .../routes/models/blueprint_models.py | 2 +- .../routes/schemas/allowed_files.json | 14 +- .../routes/schemas/allowed_files.py | 3 +- .../routes/schemas/allowed_objects.json | 9 +- .../routes/schemas/allowed_objects.py | 2 - .../geode_objects_and_output_extensions.json | 4 +- .../geode_objects_and_output_extensions.py | 2 +- .../geographic_coordinate_systems.json | 4 +- .../schemas/geographic_coordinate_systems.py | 2 +- .../routes/schemas/inspect_file.json | 4 +- .../routes/schemas/inspect_file.py | 2 +- .../routes/schemas/missing_files.json | 4 +- .../routes/schemas/missing_files.py | 2 +- .../routes/schemas/save_viewable_file.json | 4 +- .../routes/schemas/save_viewable_file.py | 2 +- src/opengeodeweb_back/test_utils.py | 12 +- src/opengeodeweb_back/utils_functions.py | 12 +- tests/test_geode_functions.py | 15 +- tests/test_models_routes.py | 55 ++--- tests/test_routes.py | 80 ++++---- tests/test_utils_functions.py | 13 +- 32 files changed, 449 insertions(+), 316 deletions(-) create mode 100644 src/opengeodeweb_back/geode_objects/geode_mesh.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_model.py create mode 100644 src/opengeodeweb_back/geode_objects/types.py diff --git a/opengeodeweb_back_schemas.json b/opengeodeweb_back_schemas.json index 928d482b..81e4505e 100644 --- a/opengeodeweb_back_schemas.json +++ b/opengeodeweb_back_schemas.json @@ -213,7 +213,7 @@ ], "type": "object", "properties": { - "input_geode_object": { + "geode_object_type": { "type": "string", "minLength": 1 }, @@ -223,7 +223,7 @@ } }, "required": [ - "input_geode_object", + "geode_object_type", "filename" ], "additionalProperties": false @@ -283,7 +283,7 @@ ], "type": "object", "properties": { - "input_geode_object": { + "geode_object_type": { "type": "string", "minLength": 1 }, @@ -293,7 +293,7 @@ } }, "required": [ - "input_geode_object", + "geode_object_type", "filename" ], "additionalProperties": false @@ -321,14 +321,14 @@ "type": "string", "minLength": 1 }, - "input_geode_object": { + "geode_object_type": { "type": "string", "minLength": 1 } }, "required": [ "filename", - "input_geode_object" + "geode_object_type" ], "additionalProperties": false }, @@ -351,13 +351,13 @@ ], "type": "object", "properties": { - "input_geode_object": { + "geode_object_type": { "type": "string", "minLength": 1 } }, "required": [ - "input_geode_object" + "geode_object_type" ], "additionalProperties": false }, @@ -369,7 +369,7 @@ ], "type": "object", "properties": { - "input_geode_object": { + "geode_object_type": { "type": "string", "minLength": 1 }, @@ -379,7 +379,7 @@ } }, "required": [ - "input_geode_object", + "geode_object_type", "filename" ], "additionalProperties": false @@ -417,17 +417,10 @@ "filename": { "type": "string", "minLength": 1 - }, - "supported_feature": { - "type": [ - "string", - "null" - ] } }, "required": [ - "filename", - "supported_feature" + "filename" ], "additionalProperties": false }, @@ -438,17 +431,8 @@ "POST" ], "type": "object", - "properties": { - "supported_feature": { - "type": [ - "string", - "null" - ] - } - }, - "required": [ - "supported_feature" - ], + "properties": {}, + "required": [], "additionalProperties": false } } diff --git a/src/opengeodeweb_back/app.py b/src/opengeodeweb_back/app.py index e5175124..1202ecb1 100644 --- a/src/opengeodeweb_back/app.py +++ b/src/opengeodeweb_back/app.py @@ -74,6 +74,7 @@ def errorhandler(e: HTTPException) -> tuple[dict[str, Any], int] | Response: @app.errorhandler(Exception) def handle_generic_exception(e: Exception) -> Response: + print("handle_generic_exception:", str(e), flush=True) return flask.make_response({"error": str(e)}, 500) diff --git a/src/opengeodeweb_back/geode_functions.py b/src/opengeodeweb_back/geode_functions.py index 486bd8b9..e3ffed58 100644 --- a/src/opengeodeweb_back/geode_functions.py +++ b/src/opengeodeweb_back/geode_functions.py @@ -9,14 +9,24 @@ from typing import Any # Local application imports -from .geode_objects import geode_objects -from .geode_objects.geode_object import GeodeType, GeodeObject, to_geode_type +from .geode_objects import geode_objects, geode_meshes, geode_models +from .geode_objects.types import ( + GeodeObjectType, + geode_object_type, + GeodeMeshType, + geode_mesh_type, + GeodeModelType, + geode_model_type, +) +from .geode_objects.geode_object import GeodeObject +from .geode_objects.geode_mesh import GeodeMesh +from .geode_objects.geode_model import GeodeModel from . import utils_functions from opengeodeweb_microservice.database.data import Data from opengeodeweb_microservice.database.connection import get_session -def data_file_path(data_id: str, filename: str | None) -> str: +def data_file_path(data_id: str, filename: str | None = None) -> str: data_folder_path = flask.current_app.config["DATA_FOLDER_PATH"] data_path = os.path.join(data_folder_path, data_id) if filename is not None: @@ -24,24 +34,56 @@ def data_file_path(data_id: str, filename: str | None) -> str: return data_path -def load_data(data_id: str) -> GeodeObject: - data_entry = Data.get(data_id) - if not data_entry: +def geode_object_from_string(value: str) -> type[GeodeObject]: + return geode_objects[geode_object_type(value)] + + +def geode_mesh_from_string(value: str) -> type[GeodeMesh]: + return geode_meshes[geode_mesh_type(value)] + + +def geode_model_from_string(value: str) -> type[GeodeModel]: + return geode_models[geode_model_type(value)] + + +def load_object_data(data_id: str) -> GeodeObject: + data = Data.get(data_id) + if not data: + flask.abort(404, f"Data with id {data_id} not found") + + file_absolute_path = data_file_path(data_id, data.native_file_name) + print("Loading file: ", file_absolute_path) + print("File exists: ", os.path.exists(file_absolute_path)) + return geode_object_from_string(data.geode_object).load(file_absolute_path) + + +def load_mesh_data(data_id: str) -> GeodeMesh: + data = Data.get(data_id) + if not data: + flask.abort(404, f"Data with id {data_id} not found") + + file_absolute_path = data_file_path(data_id, data.native_file_name) + print("Loading file: ", file_absolute_path) + print("File exists: ", os.path.exists(file_absolute_path)) + return geode_mesh_from_string(data.geode_object).load_mesh(file_absolute_path) + + +def load_model_data(data_id: str) -> GeodeModel: + data = Data.get(data_id) + if not data: flask.abort(404, f"Data with id {data_id} not found") - file_absolute_path = data_file_path(data_id, data_entry.native_file_name) + file_absolute_path = data_file_path(data_id, data.native_file_name) print("Loading file: ", file_absolute_path) print("File exists: ", os.path.exists(file_absolute_path)) - return geode_objects[to_geode_type(data_entry.geode_object)].load( - file_absolute_path - ) + return geode_model_from_string(data.geode_object).load_model(file_absolute_path) def get_data_info(data_id: str) -> Data: - data_entry = Data.get(data_id) - if not data_entry: + data = Data.get(data_id) + if not data: flask.abort(404, f"Data with id {data_id} not found") - return data_entry + return data def upload_file_path(filename: str) -> str: @@ -52,9 +94,9 @@ def upload_file_path(filename: str) -> str: def geode_object_output_extensions( geode_object: GeodeObject, -) -> dict[GeodeType, dict[str, bool]]: - results: dict[GeodeType, dict[str, bool]] = {} - for mixin_geode_object in geode_objects[geode_object.geode_type()].__mro__: +) -> dict[GeodeObjectType, dict[str, bool]]: + results: dict[GeodeObjectType, dict[str, bool]] = {} + for mixin_geode_object in geode_objects[geode_object.geode_object_type()].__mro__: output_extensions_method = getattr( mixin_geode_object, "output_extensions", None ) @@ -70,35 +112,35 @@ def geode_object_output_extensions( geode_object, f"test.{output_extension}" ) object_output_extensions[output_extension] = bool_is_saveable - if hasattr(mixin_geode_object, "geode_type"): - results[mixin_geode_object.geode_type()] = object_output_extensions + if hasattr(mixin_geode_object, "geode_object_type"): + results[mixin_geode_object.geode_object_type()] = object_output_extensions return results -# def assign_crs(geode_type: GeodeType, data, crs_name: str, info): +# def assign_crs(geode_object_type: GeodeObjectType, data, crs_name: str, info): # builder = create_builder(geode_object, data) -# geode_objects[geode_type].["crs"]["assign"](data, builder, crs_name, info) +# geode_objects[geode_object_type].["crs"]["assign"](data, builder, crs_name, info) -# def convert_crs(geode_type: GeodeType, data, crs_name: str, info): +# def convert_crs(geode_object_type: GeodeObjectType, data, crs_name: str, info): # builder = create_builder(geode_object, data) -# geode_objects[geode_type].["crs"]["convert"](data, builder, crs_name, info) +# geode_objects[geode_object_type].["crs"]["convert"](data, builder, crs_name, info) # def create_crs( -# geode_type: GeodeType, +# geode_object_type: GeodeObjectType, # data, # name: str, # input_coordiante_system, # output_coordiante_system, # ): # builder = create_builder(geode_object, data) -# geode_objects[geode_type].["crs"]["create"]( +# geode_objects[geode_object_type].["crs"]["create"]( # data, builder, name, input_coordiante_system, output_coordiante_system # ) -# def geographic_coordinate_systems_info(geode_type: GeodeType, crs): +# def geographic_coordinate_systems_info(geode_object_type: GeodeObjectType, crs): # if is_3D(geode_object): # return og_gs.GeographicCoordinateSystemInfo3D( # crs["authority"], crs["code"], crs["name"] @@ -109,7 +151,7 @@ def geode_object_output_extensions( # ) -# def coordinate_system(geode_type: GeodeType, coordinate_system): +# def coordinate_system(geode_object_type: GeodeObjectType, coordinate_system): # return og.CoordinateSystem2D( # [ # og.Vector2D( @@ -133,18 +175,18 @@ def geode_object_output_extensions( # ) -# def assign_geographic_coordinate_system_info(geode_type: GeodeType, data, input_crs): +# def assign_geographic_coordinate_system_info(geode_object_type: GeodeObjectType, data, input_crs): # info = geographic_coordinate_systems_info(geode_object, input_crs) # assign_crs(geode_object, data, input_crs["name"], info) -# def convert_geographic_coordinate_system_info(geode_type: GeodeType, data, output_crs): +# def convert_geographic_coordinate_system_info(geode_object_type: GeodeObjectType, data, output_crs): # info = geographic_coordinate_systems_info(geode_object, output_crs) # convert_crs(geode_object, data, output_crs["name"], info) # def create_coordinate_system( -# geode_type: GeodeType, data, name, input_coordinate_points, output_coordinate_points +# geode_object_type: GeodeObjectType, data, name, input_coordinate_points, output_coordinate_points # ): # input_coordiante_system = coordinate_system(geode_object, input_coordinate_points) # output_coordiante_system = coordinate_system(geode_object, output_coordinate_points) diff --git a/src/opengeodeweb_back/geode_objects/__init__.py b/src/opengeodeweb_back/geode_objects/__init__.py index 6084659e..1e30c904 100644 --- a/src/opengeodeweb_back/geode_objects/__init__.py +++ b/src/opengeodeweb_back/geode_objects/__init__.py @@ -12,11 +12,20 @@ import geode_viewables as viewables # Local application imports -from .geode_object import GeodeType, GeodeObject +from .types import GeodeObjectType, GeodeMeshType, GeodeModelType +from .geode_object import GeodeObject +from .geode_model import GeodeModel +from .geode_mesh import GeodeMesh from .geode_brep import GeodeBRep -geode_objects: dict[GeodeType, type[GeodeObject]] = {"BRep": GeodeBRep} +geode_meshes: dict[GeodeMeshType, type[GeodeMesh]] = {} +geode_models: dict[GeodeModelType, type[GeodeModel]] = {"BRep": GeodeBRep} + +GeodeObjectsDict = dict[GeodeObjectType, type[GeodeObject]] +geode_objects: GeodeObjectsDict = {} +geode_objects.update(cast(GeodeObjectsDict, geode_meshes)) +geode_objects.update(cast(GeodeObjectsDict, geode_models)) mesh = "mesh" diff --git a/src/opengeodeweb_back/geode_objects/geode_brep.py b/src/opengeodeweb_back/geode_objects/geode_brep.py index 04170317..aade7514 100644 --- a/src/opengeodeweb_back/geode_objects/geode_brep.py +++ b/src/opengeodeweb_back/geode_objects/geode_brep.py @@ -1,10 +1,17 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports import opengeode as og +import opengeode_inspector as og_inspector import geode_viewables as viewables -from .geode_object import GeodeObject, GeodeType, ViewerType +# Local application imports +from .types import GeodeModelType, ViewerType +from .geode_model import GeodeModel, ComponentRegistry -class GeodeBRep(GeodeObject): +class GeodeBRep(GeodeModel): brep: og.BRep def __init__(self, brep: og.BRep | None = None) -> None: @@ -12,13 +19,9 @@ def __init__(self, brep: og.BRep | None = None) -> None: super().__init__(self.brep) @classmethod - def geode_type(cls) -> GeodeType: + def geode_model_type(cls) -> GeodeModelType: return "BRep" - @classmethod - def viewer_type(cls) -> ViewerType: - return "model" - def native_extension(self) -> str: return self.brep.native_extension() @@ -34,7 +37,7 @@ def builder(self) -> og.BRepBuilder: return og.BRepBuilder(self.brep) @classmethod - def load(self, filename: str) -> "GeodeBRep": + def load_model(cls, filename: str) -> GeodeBRep: return GeodeBRep(og.load_brep(filename)) @classmethod @@ -68,3 +71,9 @@ def save_viewable(self, filename_without_extension: str) -> str: def save_light_viewable(self, filename_without_extension: str) -> str: return viewables.save_light_viewable_brep(self.brep, filename_without_extension) + + def mesh_components(self) -> ComponentRegistry: + return self.brep.mesh_components() + + def inspect(self) -> og_inspector.BRepInspectionResult: + return og_inspector.inspect_brep(self.brep) diff --git a/src/opengeodeweb_back/geode_objects/geode_mesh.py b/src/opengeodeweb_back/geode_objects/geode_mesh.py new file mode 100644 index 00000000..b7162e34 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_mesh.py @@ -0,0 +1,33 @@ +# Standard library imports +from __future__ import annotations +from abc import ABC, abstractmethod +from typing import Literal, Any, get_args, cast + +# Third party imports +import opengeode as og + +# Local application imports +from .types import GeodeObjectType, GeodeMeshType, ViewerType +from .geode_object import GeodeObject + + +class GeodeMesh(GeodeObject): + @classmethod + def load(cls, filename: str) -> GeodeObject: + return cls.load_mesh(filename) + + @classmethod + @abstractmethod + def load_mesh(cls, filename: str) -> GeodeMesh: ... + + @classmethod + def geode_object_type(cls) -> GeodeObjectType: + return cls.geode_mesh_type() + + @classmethod + @abstractmethod + def geode_mesh_type(cls) -> GeodeMeshType: ... + + @classmethod + def viewer_type(cls) -> ViewerType: + return "mesh" diff --git a/src/opengeodeweb_back/geode_objects/geode_model.py b/src/opengeodeweb_back/geode_objects/geode_model.py new file mode 100644 index 00000000..399bd6b9 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_model.py @@ -0,0 +1,38 @@ +# Standard library imports +from __future__ import annotations +from abc import ABC, abstractmethod +from typing import Literal, Any, get_args, cast + +# Third party imports +import opengeode as og + +# Local application imports +from .types import GeodeObjectType, GeodeModelType, ViewerType +from .geode_object import GeodeObject + +ComponentRegistry = dict[og.ComponentType, list[og.uuid]] + + +class GeodeModel(GeodeObject): + @classmethod + def load(cls, filename: str) -> GeodeObject: + return cls.load_model(filename) + + @classmethod + @abstractmethod + def load_model(cls, filename: str) -> GeodeModel: ... + + @classmethod + def geode_object_type(cls) -> GeodeObjectType: + return cls.geode_model_type() + + @classmethod + @abstractmethod + def geode_model_type(cls) -> GeodeModelType: ... + + @classmethod + def viewer_type(cls) -> ViewerType: + return "model" + + @abstractmethod + def mesh_components(self) -> ComponentRegistry: ... diff --git a/src/opengeodeweb_back/geode_objects/geode_object.py b/src/opengeodeweb_back/geode_objects/geode_object.py index 2321e103..1bb0f85e 100644 --- a/src/opengeodeweb_back/geode_objects/geode_object.py +++ b/src/opengeodeweb_back/geode_objects/geode_object.py @@ -5,26 +5,9 @@ # Third party imports import opengeode as og -import opengeode_io as og_io -import opengeode_inspector as og_inspector -import opengeode_geosciences as og_gs -import opengeode_geosciencesio as og_gs_io -import geode_viewables as viewables # Local application imports - - -GeodeType = Literal["BRep"] - - -def to_geode_type(value: str) -> GeodeType: - allowed = get_args(GeodeType) - if value not in allowed: - raise ValueError(f"Invalid GeodeType: {value!r}. Must be one of {allowed}") - return cast(GeodeType, value) - - -ViewerType = Literal["mesh", "model"] +from .types import GeodeObjectType, ViewerType class GeodeObject(ABC): @@ -35,7 +18,7 @@ def __init__(self, identifier: og.Identifier | None = None) -> None: @classmethod @abstractmethod - def geode_type(cls) -> GeodeType: ... + def geode_object_type(cls) -> GeodeObjectType: ... @classmethod @abstractmethod @@ -91,6 +74,9 @@ def save_viewable(self, filename_without_extension: str) -> str: ... @abstractmethod def save_light_viewable(self, filename_without_extension: str) -> str: ... + @abstractmethod + def inspect(self) -> Any: ... + mesh = "mesh" model = "model" diff --git a/src/opengeodeweb_back/geode_objects/types.py b/src/opengeodeweb_back/geode_objects/types.py new file mode 100644 index 00000000..f74c864e --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/types.py @@ -0,0 +1,51 @@ +# Standard library imports +from typing import Literal, get_args, cast + +# Third party imports + +# Local application imports + + +GeodeSurfaceMeshType = Literal["PolygonalSurface3D"] +GeodeMeshType = Literal["VertexSet"] | GeodeSurfaceMeshType +GeodeModelType = Literal["BRep"] +GeodeObjectType = GeodeMeshType | GeodeModelType + + +def _flatten_literal_args(literal: object) -> tuple[str, ...]: + flattened: list[str] = [] + for arg in get_args(literal): + if isinstance(arg, str): + flattened.append(arg) + else: + flattened.extend(_flatten_literal_args(arg)) + return tuple(flattened) + + +GeodeSurfaceMeshType_values = _flatten_literal_args(GeodeSurfaceMeshType) +GeodeMeshType_values = _flatten_literal_args(GeodeMeshType) +GeodeModelType_values = _flatten_literal_args(GeodeModelType) +GeodeObjectType_values = _flatten_literal_args(GeodeObjectType) + + +def geode_object_type(value: str) -> GeodeObjectType: + if value not in GeodeObjectType_values: + raise ValueError( + f"Invalid GeodeObjectType: {value!r}. Must be one of {allowed}" + ) + return cast(GeodeObjectType, value) + + +def geode_mesh_type(value: str) -> GeodeMeshType: + if value not in GeodeMeshType_values: + raise ValueError(f"Invalid GeodeMeshType: {value!r}. Must be one of {allowed}") + return cast(GeodeMeshType, value) + + +def geode_model_type(value: str) -> GeodeModelType: + if value not in GeodeModelType_values: + raise ValueError(f"Invalid GeodeModelType: {value!r}. Must be one of {allowed}") + return cast(GeodeModelType, value) + + +ViewerType = Literal["mesh", "model"] diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index 8dab4d48..69e8e0a2 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -2,20 +2,24 @@ import os import time import shutil +from typing import Any # Third party imports import flask import werkzeug import zipfile +import opengeode_geosciences as og_geosciences from opengeodeweb_microservice.schemas import get_schemas_dict +from opengeodeweb_microservice.database.data import Data +from opengeodeweb_microservice.database.connection import get_session +from opengeodeweb_microservice.database import connection # Local application imports -from opengeodeweb_back import geode_functions, utils_functions from .models import blueprint_models from . import schemas -from opengeodeweb_microservice.database.data import Data -from opengeodeweb_microservice.database.connection import get_session -from opengeodeweb_microservice.database import connection +from opengeodeweb_back import geode_functions, utils_functions +from opengeodeweb_back.geode_objects import geode_objects +from opengeodeweb_back.geode_objects.types import geode_object_type routes = flask.Blueprint("routes", __name__, url_prefix="/opengeodeweb_back") @@ -36,7 +40,10 @@ def allowed_files() -> flask.Response: utils_functions.validate_request(flask.request, schemas_dict["allowed_files"]) params = schemas.AllowedFiles.from_dict(flask.request.get_json()) - extensions = geode_functions.list_input_extensions(params.supported_feature) + extensions: set[str] = set() + for geode_object in geode_objects.values(): + for extension in geode_object.input_extensions(): + extensions.add(extension) return flask.make_response({"extensions": extensions}, 200) @@ -63,32 +70,22 @@ def allowed_objects() -> flask.Response: utils_functions.validate_request(flask.request, schemas_dict["allowed_objects"]) params = schemas.AllowedObjects.from_dict(flask.request.get_json()) file_absolute_path = geode_functions.upload_file_path(params.filename) - allowed_objects = geode_functions.list_geode_objects( - file_absolute_path, params.supported_feature + file_extension = utils_functions.extension_from_filename( + os.path.basename(file_absolute_path) ) + allowed_objects = {} + for geode_object_type, geode_object in geode_objects.items(): + if file_extension not in geode_object.input_extensions(): + continue + loadability_score = geode_object.is_loadable(file_absolute_path) + priority_score = geode_object.object_priority(file_absolute_path) + allowed_objects[geode_object] = { + "is_loadable": loadability_score, + "object_priority": priority_score, + } return flask.make_response({"allowed_objects": allowed_objects}, 200) -# def list_geode_objects( -# file_absolute_path: str, -# key: str | None = None, -# ): -# return_dict = {} -# file_extension = utils_functions.extension_from_filename( -# os.path.basename(file_absolute_path) -# ) -# geode_objects_filtered_list = filter_geode_objects(key) -# for geode_object in geode_objects_filtered_list: -# if has_creator(geode_object, file_extension): -# loadability_score = is_loadable(geode_object, file_absolute_path) -# priority_score = object_priority(geode_object, file_absolute_path) -# return_dict[geode_object] = { -# "is_loadable": loadability_score, -# "object_priority": priority_score, -# } -# return return_dict - - @routes.route( schemas_dict["missing_files"]["route"], methods=schemas_dict["missing_files"]["methods"], @@ -97,23 +94,20 @@ def missing_files() -> flask.Response: utils_functions.validate_request(flask.request, schemas_dict["missing_files"]) params = schemas.MissingFiles.from_dict(flask.request.get_json()) file_path = geode_functions.upload_file_path(params.filename) - - additional_files = geode_functions.additional_files( - params.input_geode_object, + geode_object = geode_functions.geode_object_from_string(params.geode_object_type) + additional_files = geode_object.additional_files( file_path, ) - has_missing_files = any( file.is_missing for file in additional_files.mandatory_files + additional_files.optional_files ) - mandatory_files = [ os.path.basename(file.filename) for file in additional_files.mandatory_files if file.is_missing ] - additional_files = [ + additional_files_array = [ os.path.basename(file.filename) for file in additional_files.optional_files if file.is_missing @@ -123,7 +117,7 @@ def missing_files() -> flask.Response: { "has_missing_files": has_missing_files, "mandatory_files": mandatory_files, - "additional_files": additional_files, + "additional_files": additional_files_array, }, 200, ) @@ -138,7 +132,12 @@ def crs_converter_geographic_coordinate_systems() -> flask.Response: flask.request, schemas_dict["geographic_coordinate_systems"] ) params = schemas.GeographicCoordinateSystems.from_dict(flask.request.get_json()) - infos = geode_functions.geographic_coordinate_systems(params.input_geode_object) + geode_object = geode_functions.geode_object_from_string(params.geode_object_type) + infos = ( + og_geosciences.GeographicCoordinateSystem3D.geographic_coordinate_systems() + if geode_object.is_3D() + else og_geosciences.GeographicCoordinateSystem2D.geographic_coordinate_systems() + ) crs_list = [] for info in infos: crs = {} @@ -146,17 +145,9 @@ def crs_converter_geographic_coordinate_systems() -> flask.Response: crs["code"] = info.code crs["authority"] = info.authority crs_list.append(crs) - return flask.make_response({"crs_list": crs_list}, 200) -# def geographic_coordinate_systems(geode_type: GeodeType): -# if is_3D(geode_object): -# return og_gs.GeographicCoordinateSystem3D.geographic_coordinate_systems() -# else: -# return og_gs.GeographicCoordinateSystem2D.geographic_coordinate_systems() - - @routes.route( schemas_dict["inspect_file"]["route"], methods=schemas_dict["inspect_file"]["methods"], @@ -165,36 +156,40 @@ def inspect_file() -> flask.Response: utils_functions.validate_request(flask.request, schemas_dict["inspect_file"]) params = schemas.InspectFile.from_dict(flask.request.get_json()) file_path = geode_functions.upload_file_path(params.filename) - data = geode_functions.load(params.input_geode_object, file_path) - class_inspector = geode_functions.inspect(params.input_geode_object, data) - inspection_result = geode_functions.get_inspector_children(class_inspector) + geode_object = geode_functions.geode_object_from_string( + params.geode_object_type + ).load(file_path) + inspection_data = geode_object.inspect() + inspection_result = extract_inspector_result(inspection_data) return flask.make_response({"inspection_result": inspection_result}, 200) -# def get_inspector_children(obj): -# new_object = {} - -# if "inspection_type" in dir(obj): -# new_object["title"] = obj.inspection_type() -# new_object["nb_issues"] = 0 -# new_object["children"] = [] -# for child in dir(obj): -# if not child.startswith("__") and not child in [ -# "inspection_type", -# "string", -# ]: -# child_instance = obj.__getattribute__(child) -# child_object = get_inspector_children(child_instance) -# new_object["children"].append(child_object) -# new_object["nb_issues"] += child_object["nb_issues"] -# else: -# new_object["title"] = obj.description() -# nb_issues = obj.nb_issues() -# new_object["nb_issues"] = nb_issues -# if nb_issues > 0: -# issues = obj.string().split("\n") -# new_object["issues"] = issues -# return new_object +def extract_inspector_result(inspection_data: Any) -> object: + new_object = {} + + if hasattr(inspection_data, "inspection_type"): + new_object["title"] = inspection_data.inspection_type() + new_object["nb_issues"] = 0 + new_object["children"] = [] + for child in dir(inspection_data): + if child.startswith("__") or child in [ + "inspection_type", + "string", + ]: + continue + child_instance = getattr(inspection_data, child) + child_object = extract_inspector_result(child_instance) + new_object["children"].append(child_object) + if hasattr(child_object, "nb_issues"): + new_object["nb_issues"] += child_object.nb_issues() + else: + new_object["title"] = inspection_data.description() + nb_issues = inspection_data.nb_issues() + new_object["nb_issues"] = nb_issues + if nb_issues > 0: + issues = inspection_data.string().split("\n") + new_object["issues"] = issues + return new_object @routes.route( @@ -207,12 +202,11 @@ def geode_objects_and_output_extensions() -> flask.Response: ) params = schemas.GeodeObjectsAndOutputExtensions.from_dict(flask.request.get_json()) file_path = geode_functions.upload_file_path(params.filename) - data = geode_functions.load( - params.input_geode_object, - file_path, - ) + geode_object = geode_functions.geode_object_from_string( + params.geode_object_type + ).load(file_path) geode_objects_and_output_extensions = ( - geode_functions.geode_objects_output_extensions(params.input_geode_object, data) + geode_functions.geode_object_output_extensions(geode_object) ) return flask.make_response( {"geode_objects_and_output_extensions": geode_objects_and_output_extensions}, @@ -220,23 +214,6 @@ def geode_objects_and_output_extensions() -> flask.Response: ) -# def geode_objects_output_extensions(geode_type: GeodeType, data): -# geode_objects_output_extensions_dict = {} -# output_extensions = geode_object_output_extensions(geode_object) -# extensions_dict = {} -# for output_extension in output_extensions: -# bool_is_saveable = is_saveable(geode_object, data, f"test.{output_extension}") -# extensions_dict[output_extension] = {"is_saveable": bool_is_saveable} -# geode_objects_output_extensions_dict[geode_object] = extensions_dict - -# if "parent" in geode_objects[geode_type].keys(): -# parent_geode_object = geode_objects[geode_type]["parent"] -# geode_objects_output_extensions_dict.update( -# geode_objects_output_extensions(parent_geode_object, data) -# ) -# return geode_objects_output_extensions_dict - - @routes.route( schemas_dict["save_viewable_file"]["route"], methods=schemas_dict["save_viewable_file"]["methods"], @@ -246,7 +223,7 @@ def save_viewable_file() -> flask.Response: params = schemas.SaveViewableFile.from_dict(flask.request.get_json()) return flask.make_response( utils_functions.generate_native_viewable_and_light_viewable_from_file( - geode_object=params.input_geode_object, + geode_object_type=geode_object_type(params.geode_object_type), input_filename=params.filename, ), 200, @@ -260,7 +237,7 @@ def save_viewable_file() -> flask.Response: def texture_coordinates() -> flask.Response: utils_functions.validate_request(flask.request, schemas_dict["texture_coordinates"]) params = schemas.TextureCoordinates.from_dict(flask.request.get_json()) - data = geode_functions.load_data(params.id) + data = geode_functions.load_object_data(params.id) texture_coordinates = data.texture_manager().texture_names() return flask.make_response({"texture_coordinates": texture_coordinates}, 200) @@ -274,7 +251,7 @@ def vertex_attribute_names() -> flask.Response: flask.request, schemas_dict["vertex_attribute_names"] ) params = schemas.VertexAttributeNames.from_dict(flask.request.get_json()) - data = geode_functions.load_data(params.id) + data = geode_functions.load_object_data(params.id) vertex_attribute_names = data.vertex_attribute_manager().attribute_names() return flask.make_response( { @@ -293,7 +270,7 @@ def polygon_attribute_names() -> flask.Response: flask.request, schemas_dict["polygon_attribute_names"] ) params = schemas.PolygonAttributeNames.from_dict(flask.request.get_json()) - data = geode_functions.load_data(params.id) + data = geode_functions.load_object_data(params.id) polygon_attribute_names = data.polygon_attribute_manager().attribute_names() return flask.make_response( { @@ -312,7 +289,7 @@ def polyhedron_attribute_names() -> flask.Response: flask.request, schemas_dict["polyhedron_attribute_names"] ) params = schemas.PolyhedronAttributeNames.from_dict(flask.request.get_json()) - data = geode_functions.load_data(params.id) + data = geode_functions.load_object_data(params.id) polyhedron_attribute_names = data.polyhedron_attribute_manager().attribute_names() return flask.make_response( { @@ -446,25 +423,27 @@ def import_project() -> flask.Response: rows = session.query(Data).all() with get_session() as session: - for data_entry in rows: - data_path = geode_functions.data_file_path(data_entry.id) - viewable_name = data_entry.viewable_file_name + for data in rows: + data_path = geode_functions.data_file_path(data.id) + viewable_name = data.viewable_file_name if viewable_name: - vpath = geode_functions.data_file_path(data_entry.id, viewable_name) + vpath = geode_functions.data_file_path(data.id, viewable_name) if os.path.isfile(vpath): continue - input_file = str(data_entry.input_file or "") + input_file = str(data.input_file or "") if not input_file: continue - input_full = geode_functions.data_file_path(data_entry.id, input_file) + input_full = geode_functions.data_file_path(data.id, input_file) if not os.path.isfile(input_full): continue - data_object = geode_functions.load(data_entry.geode_object, input_full) + geode_object = geode_functions.geode_object_from_string( + data.geode_object + ).load(input_full) utils_functions.save_all_viewables_and_return_info( - data_entry.geode_object, data_object, data_entry, data_path + geode_object, data, data_path ) session.commit() diff --git a/src/opengeodeweb_back/routes/create/blueprint_create.py b/src/opengeodeweb_back/routes/create/blueprint_create.py index 10766664..3cfcd7ac 100644 --- a/src/opengeodeweb_back/routes/create/blueprint_create.py +++ b/src/opengeodeweb_back/routes/create/blueprint_create.py @@ -80,7 +80,7 @@ def create_voi() -> flask.Response: if not aoi_data: flask.abort(404, f"AOI with id {params.aoi_id} not found") - aoi_object = geode_functions.load_data(params.aoi_id) + aoi_object = geode_functions.load_object_data(params.aoi_id) nb_points = aoi_object.nb_vertices() diff --git a/src/opengeodeweb_back/routes/models/blueprint_models.py b/src/opengeodeweb_back/routes/models/blueprint_models.py index ecc5e88a..fbfb9c41 100644 --- a/src/opengeodeweb_back/routes/models/blueprint_models.py +++ b/src/opengeodeweb_back/routes/models/blueprint_models.py @@ -40,7 +40,7 @@ def uuid_to_flat_index() -> flask.Response: def extract_uuids_endpoint() -> flask.Response: utils_functions.validate_request(flask.request, schemas_dict["mesh_components"]) params = schemas.MeshComponents.from_dict(flask.request.get_json()) - model = geode_functions.load_data(params.id) + model = geode_functions.load_model_data(params.id) mesh_components = model.mesh_components() uuid_dict = {} for mesh_component, ids in mesh_components.items(): diff --git a/src/opengeodeweb_back/routes/schemas/allowed_files.json b/src/opengeodeweb_back/routes/schemas/allowed_files.json index 32f5d394..0734d40f 100644 --- a/src/opengeodeweb_back/routes/schemas/allowed_files.json +++ b/src/opengeodeweb_back/routes/schemas/allowed_files.json @@ -1,12 +1,10 @@ { "route": "/allowed_files", - "methods": ["POST"], + "methods": [ + "POST" + ], "type": "object", - "properties": { - "supported_feature": { - "type": ["string", "null"] - } - }, - "required": ["supported_feature"], + "properties": {}, + "required": [], "additionalProperties": false -} +} \ No newline at end of file diff --git a/src/opengeodeweb_back/routes/schemas/allowed_files.py b/src/opengeodeweb_back/routes/schemas/allowed_files.py index edebd493..f0227012 100644 --- a/src/opengeodeweb_back/routes/schemas/allowed_files.py +++ b/src/opengeodeweb_back/routes/schemas/allowed_files.py @@ -1,6 +1,5 @@ from dataclasses_json import DataClassJsonMixin from dataclasses import dataclass -from typing import Optional @dataclass @@ -8,4 +7,4 @@ class AllowedFiles(DataClassJsonMixin): def __post_init__(self) -> None: print(self, flush=True) - supported_feature: Optional[str] = None + pass diff --git a/src/opengeodeweb_back/routes/schemas/allowed_objects.json b/src/opengeodeweb_back/routes/schemas/allowed_objects.json index 7aadc618..7fe189c0 100644 --- a/src/opengeodeweb_back/routes/schemas/allowed_objects.json +++ b/src/opengeodeweb_back/routes/schemas/allowed_objects.json @@ -8,17 +8,10 @@ "filename": { "type": "string", "minLength": 1 - }, - "supported_feature": { - "type": [ - "string", - "null" - ] } }, "required": [ - "filename", - "supported_feature" + "filename" ], "additionalProperties": false } \ No newline at end of file diff --git a/src/opengeodeweb_back/routes/schemas/allowed_objects.py b/src/opengeodeweb_back/routes/schemas/allowed_objects.py index 9ee550c7..f0c74b75 100644 --- a/src/opengeodeweb_back/routes/schemas/allowed_objects.py +++ b/src/opengeodeweb_back/routes/schemas/allowed_objects.py @@ -1,6 +1,5 @@ from dataclasses_json import DataClassJsonMixin from dataclasses import dataclass -from typing import Optional @dataclass @@ -9,4 +8,3 @@ def __post_init__(self) -> None: print(self, flush=True) filename: str - supported_feature: Optional[str] = None diff --git a/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.json b/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.json index 8002c3ef..5f145f58 100644 --- a/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.json +++ b/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.json @@ -5,7 +5,7 @@ ], "type": "object", "properties": { - "input_geode_object": { + "geode_object_type": { "type": "string", "minLength": 1 }, @@ -15,7 +15,7 @@ } }, "required": [ - "input_geode_object", + "geode_object_type", "filename" ], "additionalProperties": false diff --git a/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py b/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py index 888178c5..5dedb454 100644 --- a/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py +++ b/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py @@ -8,4 +8,4 @@ def __post_init__(self) -> None: print(self, flush=True) filename: str - input_geode_object: str + geode_object_type: str diff --git a/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.json b/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.json index 8fcbea82..6472abb8 100644 --- a/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.json +++ b/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.json @@ -5,13 +5,13 @@ ], "type": "object", "properties": { - "input_geode_object": { + "geode_object_type": { "type": "string", "minLength": 1 } }, "required": [ - "input_geode_object" + "geode_object_type" ], "additionalProperties": false } \ No newline at end of file diff --git a/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py b/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py index 31353997..a4a307f5 100644 --- a/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py +++ b/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py @@ -7,4 +7,4 @@ class GeographicCoordinateSystems(DataClassJsonMixin): def __post_init__(self) -> None: print(self, flush=True) - input_geode_object: str + geode_object_type: str diff --git a/src/opengeodeweb_back/routes/schemas/inspect_file.json b/src/opengeodeweb_back/routes/schemas/inspect_file.json index 7ea39c23..3059bad0 100644 --- a/src/opengeodeweb_back/routes/schemas/inspect_file.json +++ b/src/opengeodeweb_back/routes/schemas/inspect_file.json @@ -9,14 +9,14 @@ "type": "string", "minLength": 1 }, - "input_geode_object": { + "geode_object_type": { "type": "string", "minLength": 1 } }, "required": [ "filename", - "input_geode_object" + "geode_object_type" ], "additionalProperties": false } \ No newline at end of file diff --git a/src/opengeodeweb_back/routes/schemas/inspect_file.py b/src/opengeodeweb_back/routes/schemas/inspect_file.py index 0e0e36ea..2c17ef2e 100644 --- a/src/opengeodeweb_back/routes/schemas/inspect_file.py +++ b/src/opengeodeweb_back/routes/schemas/inspect_file.py @@ -8,4 +8,4 @@ def __post_init__(self) -> None: print(self, flush=True) filename: str - input_geode_object: str + geode_object_type: str diff --git a/src/opengeodeweb_back/routes/schemas/missing_files.json b/src/opengeodeweb_back/routes/schemas/missing_files.json index 825a2d2c..e067d1a1 100644 --- a/src/opengeodeweb_back/routes/schemas/missing_files.json +++ b/src/opengeodeweb_back/routes/schemas/missing_files.json @@ -5,7 +5,7 @@ ], "type": "object", "properties": { - "input_geode_object": { + "geode_object_type": { "type": "string", "minLength": 1 }, @@ -15,7 +15,7 @@ } }, "required": [ - "input_geode_object", + "geode_object_type", "filename" ], "additionalProperties": false diff --git a/src/opengeodeweb_back/routes/schemas/missing_files.py b/src/opengeodeweb_back/routes/schemas/missing_files.py index 05a99f0a..cfdda06a 100644 --- a/src/opengeodeweb_back/routes/schemas/missing_files.py +++ b/src/opengeodeweb_back/routes/schemas/missing_files.py @@ -8,4 +8,4 @@ def __post_init__(self) -> None: print(self, flush=True) filename: str - input_geode_object: str + geode_object_type: str diff --git a/src/opengeodeweb_back/routes/schemas/save_viewable_file.json b/src/opengeodeweb_back/routes/schemas/save_viewable_file.json index 253fbb0e..49786cb4 100644 --- a/src/opengeodeweb_back/routes/schemas/save_viewable_file.json +++ b/src/opengeodeweb_back/routes/schemas/save_viewable_file.json @@ -5,7 +5,7 @@ ], "type": "object", "properties": { - "input_geode_object": { + "geode_object_type": { "type": "string", "minLength": 1 }, @@ -15,7 +15,7 @@ } }, "required": [ - "input_geode_object", + "geode_object_type", "filename" ], "additionalProperties": false diff --git a/src/opengeodeweb_back/routes/schemas/save_viewable_file.py b/src/opengeodeweb_back/routes/schemas/save_viewable_file.py index 754e5b32..be01b3b0 100644 --- a/src/opengeodeweb_back/routes/schemas/save_viewable_file.py +++ b/src/opengeodeweb_back/routes/schemas/save_viewable_file.py @@ -8,4 +8,4 @@ def __post_init__(self) -> None: print(self, flush=True) filename: str - input_geode_object: str + geode_object_type: str diff --git a/src/opengeodeweb_back/test_utils.py b/src/opengeodeweb_back/test_utils.py index 0888a4ad..9f7d8355 100644 --- a/src/opengeodeweb_back/test_utils.py +++ b/src/opengeodeweb_back/test_utils.py @@ -1,17 +1,23 @@ # Standard library imports +from typing import Callable # Third party imports +from flask.testing import FlaskClient # Local application imports +JsonData = dict[str, str] -def test_route_wrong_params(client, route, get_full_data): + +def test_route_wrong_params( + client: FlaskClient, route: str, get_full_data: Callable[[], JsonData] +) -> None: for key, value in get_full_data().items(): json = get_full_data() json.pop(key) response = client.post(route, json=json) assert response.status_code == 400 - error_description = response.json["description"] + error_description = response.get_json()["description"] assert "data must contain" in error_description assert f"'{key}'" in error_description @@ -19,6 +25,6 @@ def test_route_wrong_params(client, route, get_full_data): json["dumb_key"] = "dumb_value" response = client.post(route, json=json) assert response.status_code == 400 - error_description = response.json["description"] + error_description = response.get_json()["description"] assert "data must not contain" in error_description assert "'dumb_key'" in error_description diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index ba05e750..901e46b0 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -20,7 +20,7 @@ # Local application imports from . import geode_functions from .geode_objects import geode_objects -from .geode_objects.geode_object import GeodeType, GeodeObject +from .geode_objects.geode_object import GeodeObjectType, GeodeObject def increment_request_counter(current_app: flask.Flask) -> None: @@ -210,7 +210,7 @@ def save_all_viewables_and_return_info( "name": geode_object.identifier.name(), "viewer_type": data.viewer_object, "binary_light_viewable": binary_light_viewable.decode("utf-8"), - "geode_type": data.geode_object, + "geode_object_type": data.geode_object, "input_file": data.input_file or "", "additional_files": data.additional_files or [], } @@ -220,7 +220,7 @@ def generate_native_viewable_and_light_viewable_from_object( geode_object: GeodeObject, ) -> dict[str, str | list[str]]: data = Data.create( - geode_object=geode_object.geode_type(), + geode_object=geode_object.geode_object_type(), viewer_object=geode_object.viewer_type(), ) data_path = create_data_folder_from_id(data.id) @@ -228,11 +228,11 @@ def generate_native_viewable_and_light_viewable_from_object( def generate_native_viewable_and_light_viewable_from_file( - geode_type: GeodeType, input_filename: str + geode_object_type: GeodeObjectType, input_filename: str ) -> dict[str, str | list[str]]: - generic_geode_object = geode_objects[geode_type] + generic_geode_object = geode_objects[geode_object_type] data = Data.create( - geode_object=geode_type, + geode_object=geode_object_type, viewer_object=generic_geode_object.viewer_type(), input_file=input_filename, ) diff --git a/tests/test_geode_functions.py b/tests/test_geode_functions.py index b407497c..dbc8cb70 100644 --- a/tests/test_geode_functions.py +++ b/tests/test_geode_functions.py @@ -1,27 +1,26 @@ # Standard library imports import os import uuid -from typing import get_args # Third party imports # Local application imports from opengeodeweb_back import geode_functions from opengeodeweb_back.geode_objects import geode_objects -from opengeodeweb_back.geode_objects.geode_object import GeodeType +from opengeodeweb_back.geode_objects.types import GeodeObjectType_values data_folder = os.path.join(os.path.dirname(__file__), "data") def test_geode_objects() -> None: - for geode_type in get_args(GeodeType): - assert geode_type in geode_objects + for geode_object_type in GeodeObjectType_values: + assert geode_object_type in geode_objects def test_input_output() -> None: for generic_geode_object in geode_objects.values(): - print(f"\n{generic_geode_object.geode_type()=}") + print(f"\n{generic_geode_object.geode_object_type()=}") for input_extension in generic_geode_object.input_extensions(): print(f"\t{input_extension=}") file_absolute_path = os.path.join(data_folder, f"test.{input_extension}") @@ -44,10 +43,10 @@ def test_input_output() -> None: ) assert type(geode_objects_output_extensions) is dict for ( - output_geode_type, + output_geode_object_type, output_geode_extensions, ) in geode_objects_output_extensions.items(): - print(f"\t\t{output_geode_type=}") + print(f"\t\t{output_geode_object_type=}") for ( output_extension, output_is_saveable, @@ -56,7 +55,7 @@ def test_input_output() -> None: uu_id = str(uuid.uuid4()).replace("-", "") filename = f"{uu_id}.{output_extension}" if output_is_saveable: - saved_files = geode_objects[output_geode_type].save( + saved_files = geode_objects[output_geode_object_type].save( geode_object, os.path.join(os.path.abspath(f"./output"), filename), ) diff --git a/tests/test_models_routes.py b/tests/test_models_routes.py index 9507316c..f9841962 100644 --- a/tests/test_models_routes.py +++ b/tests/test_models_routes.py @@ -1,18 +1,21 @@ import os import shutil +import zipfile +import json +from flask.testing import FlaskClient +from werkzeug.datastructures import FileStorage +from pathlib import Path -from opengeodeweb_back import geode_functions from opengeodeweb_microservice.database.data import Data from opengeodeweb_microservice.database.connection import get_session -from werkzeug.datastructures import FileStorage -import zipfile -import json +from opengeodeweb_back import geode_functions +from opengeodeweb_back.geode_objects.geode_brep import GeodeBRep base_dir = os.path.abspath(os.path.dirname(__file__)) data_dir = os.path.join(base_dir, "data") -def test_model_mesh_components(client, test_id): +def test_model_mesh_components(client: FlaskClient, test_id: str) -> None: route = "/opengeodeweb_back/models/vtm_component_indices" with client.application.app_context(): @@ -23,7 +26,7 @@ def test_model_mesh_components(client, test_id): response = client.post(route, json={"id": test_id}) assert response.status_code == 200 - uuid_dict = response.json["uuid_to_flat_index"] + uuid_dict = response.get_json()["uuid_to_flat_index"] assert isinstance(uuid_dict, dict) indices = list(uuid_dict.values()) @@ -33,29 +36,29 @@ def test_model_mesh_components(client, test_id): assert isinstance(uuid, str) -def test_extract_brep_uuids(client, test_id): +def test_extract_brep_uuids(client: FlaskClient, test_id: str) -> None: route = "/opengeodeweb_back/models/mesh_components" brep_filename = os.path.join(data_dir, "cube.og_brep") with client.application.app_context(): - data_entry = Data.create( - geode_object="BRep", - viewer_object=geode_functions.get_object_type("BRep"), + data = Data.create( + geode_object=GeodeBRep.geode_object_type(), + viewer_object=GeodeBRep.viewer_type(), input_file=brep_filename, ) - data_entry.native_file_name = brep_filename + data.native_file_name = brep_filename session = get_session() if session: session.commit() - response = client.post(route, json={"id": data_entry.id}) + response = client.post(route, json={"id": data.id}) assert response.status_code == 200 - assert "uuid_dict" in response.json - uuid_dict = response.json["uuid_dict"] + assert "uuid_dict" in response.get_json() + uuid_dict = response.get_json()["uuid_dict"] assert isinstance(uuid_dict, dict) -def test_export_project_route(client, tmp_path): +def test_export_project_route(client: FlaskClient, tmp_path: Path) -> None: route = "/opengeodeweb_back/export_project" snapshot = { "styles": {"1": {"visibility": True, "opacity": 1.0, "color": [0.2, 0.6, 0.9]}} @@ -86,7 +89,7 @@ def test_export_project_route(client, tmp_path): os.remove(export_path) -def test_import_project_route(client, tmp_path): +def test_import_project_route(client: FlaskClient, tmp_path: Path) -> None: route = "/opengeodeweb_back/import_project" snapshot = { "styles": {"1": {"visibility": True, "opacity": 1.0, "color": [0.2, 0.6, 0.9]}} @@ -122,7 +125,7 @@ def test_import_project_route(client, tmp_path): ) assert resp.status_code == 200 - assert resp.json.get("snapshot") == snapshot + assert resp.get_json().get("snapshot") == snapshot assert os.path.exists(db_path) from opengeodeweb_microservice.database import connection @@ -135,7 +138,7 @@ def test_import_project_route(client, tmp_path): client.application.config["DATA_FOLDER_PATH"] = original_data_folder -def test_save_viewable_workflow_from_file(client): +def test_save_viewable_workflow_from_file(client: FlaskClient) -> None: file = os.path.join(data_dir, "cube.og_brep") upload_resp = client.put( "/opengeodeweb_back/upload_file", @@ -144,14 +147,14 @@ def test_save_viewable_workflow_from_file(client): assert upload_resp.status_code == 201 route = "/opengeodeweb_back/save_viewable_file" - payload = {"input_geode_object": "BRep", "filename": "cube.og_brep"} + payload = {"geode_object_type": "BRep", "filename": "cube.og_brep"} response = client.post(route, json=payload) assert response.status_code == 200 - data_id = response.json["id"] + data_id = response.get_json()["id"] assert isinstance(data_id, str) and len(data_id) > 0 - assert response.json["viewable_file_name"].endswith(".vtm") + assert response.get_json()["viewable_file_name"].endswith(".vtm") comp_resp = client.post( "/opengeodeweb_back/models/vtm_component_indices", json={"id": data_id} @@ -162,7 +165,7 @@ def test_save_viewable_workflow_from_file(client): assert refreshed is not None -def test_save_viewable_workflow_from_object(client): +def test_save_viewable_workflow_from_object(client: FlaskClient) -> None: route = "/opengeodeweb_back/create/create_aoi" aoi_data = { "name": "workflow_aoi", @@ -178,13 +181,13 @@ def test_save_viewable_workflow_from_object(client): response = client.post(route, json=aoi_data) assert response.status_code == 200 - data_id = response.json["id"] + data_id = response.get_json()["id"] assert isinstance(data_id, str) and len(data_id) > 0 - assert response.json["geode_object"] == "EdgedCurve3D" - assert response.json["viewable_file_name"].endswith(".vtp") + assert response.get_json()["geode_object"] == "EdgedCurve3D" + assert response.get_json()["viewable_file_name"].endswith(".vtp") attr_resp = client.post( "/opengeodeweb_back/vertex_attribute_names", json={"id": data_id} ) assert attr_resp.status_code == 200 - assert isinstance(attr_resp.json.get("vertex_attribute_names", []), list) + assert isinstance(attr_resp.get_json().get("vertex_attribute_names", []), list) diff --git a/tests/test_routes.py b/tests/test_routes.py index 79eda492..c18410b6 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -16,11 +16,16 @@ def test_allowed_files(client: FlaskClient) -> None: route = f"/opengeodeweb_back/allowed_files" - get_full_data = lambda: {"supported_feature": "None"} + + def get_full_data() -> test_utils.JsonData: + return { + "filename": "corbi.og_brep", + } + json = get_full_data() response = client.post(route, json=json) assert response.status_code == 200 - extensions = response.json["extensions"] + extensions = response.get_json()["extensions"] assert type(extensions) is list for extension in extensions: assert type(extension) is str @@ -32,16 +37,15 @@ def test_allowed_files(client: FlaskClient) -> None: def test_allowed_objects(client: FlaskClient) -> None: route = f"/opengeodeweb_back/allowed_objects" - def get_full_data(): + def get_full_data() -> test_utils.JsonData: return { "filename": "corbi.og_brep", - "supported_feature": None, } # Normal test with filename 'corbi.og_brep' response = client.post(route, json=get_full_data()) assert response.status_code == 200 - allowed_objects = response.json["allowed_objects"] + allowed_objects = response.get_json()["allowed_objects"] assert type(allowed_objects) is dict for allowed_object in allowed_objects: assert type(allowed_object) is str @@ -50,7 +54,7 @@ def get_full_data(): test_utils.test_route_wrong_params(client, route, get_full_data) -def test_upload_file(client, filename="test.og_brep"): +def test_upload_file(client: FlaskClient, filename: str = "test.og_brep") -> None: file = os.path.join(data_dir, filename) print(f"{file=}", flush=True) response = client.put( @@ -63,18 +67,18 @@ def test_upload_file(client, filename="test.og_brep"): def test_missing_files(client: FlaskClient) -> None: route = f"/opengeodeweb_back/missing_files" - def get_full_data(): + def get_full_data() -> test_utils.JsonData: return { - "input_geode_object": "BRep", + "geode_object_type": "BRep", "filename": "test.og_brep", } json = get_full_data() response = client.post(route, json=json) assert response.status_code == 200 - has_missing_files = response.json["has_missing_files"] - mandatory_files = response.json["mandatory_files"] - additional_files = response.json["additional_files"] + has_missing_files = response.get_json()["has_missing_files"] + mandatory_files = response.get_json()["mandatory_files"] + additional_files = response.get_json()["additional_files"] assert type(has_missing_files) is bool assert type(mandatory_files) is list assert type(additional_files) is list @@ -85,11 +89,15 @@ def get_full_data(): def test_geographic_coordinate_systems(client: FlaskClient) -> None: route = f"/opengeodeweb_back/geographic_coordinate_systems" - get_full_data = lambda: {"input_geode_object": "BRep"} - # Normal test with geode_object 'BRep' + + def get_full_data() -> test_utils.JsonData: + return { + "geode_object_type": "BRep", + } + response = client.post(route, json=get_full_data()) assert response.status_code == 200 - crs_list = response.json["crs_list"] + crs_list = response.get_json()["crs_list"] assert type(crs_list) is list for crs in crs_list: assert type(crs) is dict @@ -101,9 +109,9 @@ def test_geographic_coordinate_systems(client: FlaskClient) -> None: def test_inspect_file(client: FlaskClient) -> None: route = f"/opengeodeweb_back/inspect_file" - def get_full_data(): + def get_full_data() -> test_utils.JsonData: return { - "input_geode_object": "BRep", + "geode_object_type": "BRep", "filename": "corbi.og_brep", } @@ -112,7 +120,7 @@ def get_full_data(): # Normal test with geode_object 'BRep' response = client.post(route, json=json) assert response.status_code == 200 - inspection_result = response.json["inspection_result"] + inspection_result = response.get_json()["inspection_result"] assert type(inspection_result) is dict # Test all params @@ -122,16 +130,16 @@ def get_full_data(): def test_geode_objects_and_output_extensions(client: FlaskClient) -> None: route = "/opengeodeweb_back/geode_objects_and_output_extensions" - def get_full_data(): + def get_full_data() -> test_utils.JsonData: return { - "input_geode_object": "BRep", + "geode_object_type": "BRep", "filename": "corbi.og_brep", } response = client.post(route, json=get_full_data()) assert response.status_code == 200 - geode_objects_and_output_extensions = response.json[ + geode_objects_and_output_extensions = response.get_json()[ "geode_objects_and_output_extensions" ] assert type(geode_objects_and_output_extensions) is dict @@ -149,32 +157,32 @@ def test_save_viewable_file(client: FlaskClient) -> None: test_upload_file(client, filename="corbi.og_brep") route = f"/opengeodeweb_back/save_viewable_file" - def get_full_data(): + def get_full_data() -> test_utils.JsonData: return { - "input_geode_object": "BRep", + "geode_object_type": "BRep", "filename": "corbi.og_brep", } # Normal test with filename 'corbi.og_brep' response = client.post(route, json=get_full_data()) assert response.status_code == 200 - native_file_name = response.json["native_file_name"] + native_file_name = response.get_json()["native_file_name"] assert type(native_file_name) is str - viewable_file_name = response.json["viewable_file_name"] + viewable_file_name = response.get_json()["viewable_file_name"] assert type(viewable_file_name) is str - id = response.json.get("id") + id = response.get_json().get("id") assert type(id) is str - object_type = response.json["object_type"] + object_type = response.get_json()["object_type"] assert type(object_type) is str assert object_type in ["model", "mesh"] - binary_light_viewable = response.json["binary_light_viewable"] + binary_light_viewable = response.get_json()["binary_light_viewable"] assert type(binary_light_viewable) is str # Test all params test_utils.test_route_wrong_params(client, route, get_full_data) -def test_texture_coordinates(client, test_id): +def test_texture_coordinates(client: FlaskClient, test_id: str) -> None: with client.application.app_context(): file = os.path.join(data_dir, "hat.vtp") data = Data.create( @@ -194,13 +202,13 @@ def test_texture_coordinates(client, test_id): "/opengeodeweb_back/texture_coordinates", json={"id": data.id} ) assert response.status_code == 200 - texture_coordinates = response.json["texture_coordinates"] + texture_coordinates = response.get_json()["texture_coordinates"] assert type(texture_coordinates) is list for texture_coordinate in texture_coordinates: assert type(texture_coordinate) is str -def test_vertex_attribute_names(client, test_id): +def test_vertex_attribute_names(client: FlaskClient, test_id: str) -> None: route = f"/opengeodeweb_back/vertex_attribute_names" with client.application.app_context(): @@ -220,13 +228,13 @@ def test_vertex_attribute_names(client, test_id): assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) assert response.status_code == 200 - vertex_attribute_names = response.json["vertex_attribute_names"] + vertex_attribute_names = response.get_json()["vertex_attribute_names"] assert type(vertex_attribute_names) is list for vertex_attribute_name in vertex_attribute_names: assert type(vertex_attribute_name) is str -def test_polygon_attribute_names(client, test_id): +def test_polygon_attribute_names(client: FlaskClient, test_id: str) -> None: route = f"/opengeodeweb_back/polygon_attribute_names" with client.application.app_context(): @@ -246,13 +254,13 @@ def test_polygon_attribute_names(client, test_id): assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) assert response.status_code == 200 - polygon_attribute_names = response.json["polygon_attribute_names"] + polygon_attribute_names = response.get_json()["polygon_attribute_names"] assert type(polygon_attribute_names) is list for polygon_attribute_name in polygon_attribute_names: assert type(polygon_attribute_name) is str -def test_polyhedron_attribute_names(client, test_id): +def test_polyhedron_attribute_names(client: FlaskClient, test_id: str) -> None: route = f"/opengeodeweb_back/polyhedron_attribute_names" with client.application.app_context(): @@ -271,9 +279,9 @@ def test_polyhedron_attribute_names(client, test_id): os.makedirs(os.path.dirname(data_path), exist_ok=True) assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) - print(response.json) + print(response.get_json()) assert response.status_code == 200 - polyhedron_attribute_names = response.json["polyhedron_attribute_names"] + polyhedron_attribute_names = response.get_json()["polyhedron_attribute_names"] assert type(polyhedron_attribute_names) is list for polyhedron_attribute_name in polyhedron_attribute_names: assert type(polyhedron_attribute_name) is str diff --git a/tests/test_utils_functions.py b/tests/test_utils_functions.py index 8de1e09a..4710a070 100644 --- a/tests/test_utils_functions.py +++ b/tests/test_utils_functions.py @@ -16,7 +16,6 @@ from opengeodeweb_microservice.database.data import Data from opengeodeweb_microservice.database.connection import get_session from opengeodeweb_back import geode_functions, utils_functions -from opengeodeweb_back.geode_objects.geode_object import to_geode_type from opengeodeweb_back.geode_objects.geode_brep import GeodeBRep base_dir = os.path.abspath(os.path.dirname(__file__)) @@ -112,7 +111,7 @@ def test_save_all_viewables_and_return_info(client: FlaskClient) -> None: additional_files = ["additional_file.txt"] data_entry = Data.create( - geode_object=geode_object.geode_type(), + geode_object=geode_object.geode_object_type(), viewer_object=geode_object.viewer_type(), input_file=input_file, additional_files=additional_files, @@ -135,14 +134,14 @@ def test_save_all_viewables_and_return_info(client: FlaskClient) -> None: assert re.match(r"[0-9a-f]{32}", result["id"]) assert isinstance(result["viewer_type"], str) assert isinstance(result["binary_light_viewable"], str) - assert result["geode_type"] == geode_object.geode_type() + assert result["geode_object_type"] == geode_object.geode_object_type() assert result["input_file"] == input_file db_entry = Data.get(result["id"]) assert db_entry is not None assert db_entry.native_file_name == result["native_file_name"] assert db_entry.viewable_file_name == result["viewable_file_name"] - assert db_entry.geode_object == geode_object.geode_type() + assert db_entry.geode_object == geode_object.geode_object_type() assert db_entry.input_file == input_file assert db_entry.additional_files == additional_files @@ -156,7 +155,7 @@ def test_save_all_viewables_commits_to_db(client: FlaskClient) -> None: geode_object = GeodeBRep.load(os.path.join(data_dir, "test.og_brep")) input_file = "test.og_brep" data_entry = Data.create( - geode_object=geode_object.geode_type(), + geode_object=geode_object.geode_object_type(), viewer_object=geode_object.viewer_type(), input_file=input_file, additional_files=[], @@ -203,10 +202,8 @@ def test_generate_native_viewable_and_light_viewable_from_file( ) -> None: app = client.application with app.app_context(): - geode_type = to_geode_type("BRep") - input_filename = "test.og_brep" result = utils_functions.generate_native_viewable_and_light_viewable_from_file( - geode_type, input_filename + GeodeBRep.geode_object_type(), "test.og_brep" ) assert isinstance(result, dict) From 831f7f7807ea142c067267be174a7fc2301221c9 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 20 Nov 2025 15:56:00 +0100 Subject: [PATCH 05/21] wip --- .../geode_objects/__init__.py | 237 ------------------ .../geode_objects/geode_brep.py | 25 +- .../geode_objects/geode_cross_section.py | 75 ++++++ .../geode_objects/geode_edged_curve2d.py | 80 ++++++ .../geode_objects/geode_edged_curve3d.py | 80 ++++++ .../geode_objects/geode_graph.py | 76 ++++++ .../geode_implicit_cross_section.py | 81 ++++++ .../geode_implicit_structural_model.py | 85 +++++++ .../geode_objects/geode_point_set2d.py | 80 ++++++ .../geode_objects/geode_point_set3d.py | 80 ++++++ .../geode_objects/geode_raster_image2d.py | 80 ++++++ .../geode_objects/geode_raster_image3d.py | 80 ++++++ .../geode_objects/geode_section.py | 81 ++++++ .../geode_objects/geode_structural_model.py | 78 ++++++ .../geode_objects/geode_vertex_set.py | 76 ++++++ src/opengeodeweb_back/geode_objects/types.py | 33 ++- 16 files changed, 1084 insertions(+), 243 deletions(-) create mode 100644 src/opengeodeweb_back/geode_objects/geode_cross_section.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_graph.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_implicit_cross_section.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_implicit_structural_model.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_point_set2d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_point_set3d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_raster_image2d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_raster_image3d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_section.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_structural_model.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_vertex_set.py diff --git a/src/opengeodeweb_back/geode_objects/__init__.py b/src/opengeodeweb_back/geode_objects/__init__.py index 1e30c904..93824919 100644 --- a/src/opengeodeweb_back/geode_objects/__init__.py +++ b/src/opengeodeweb_back/geode_objects/__init__.py @@ -28,126 +28,35 @@ geode_objects.update(cast(GeodeObjectsDict, geode_models)) -mesh = "mesh" -model = "model" - -points = "points" -edges = "edges" -polygons = "polygons" -polyhedrons = "polyhedrons" - - # def geode_objects_dict(): # return { # "BRep": { -# "class": og.BRep, -# "input_factory": og.BRepInputFactory, -# "output_factory": og.BRepOutputFactory, -# "additional_files": og.brep_additional_files, -# "is_loadable": og.is_brep_loadable, -# "object_priority": og.brep_object_priority, -# "load": og.load_brep, -# "is_saveable": og.is_brep_saveable, -# "save": og.save_brep, -# "builder": og.BRepBuilder, # "crs": { # "assign": og_gs.assign_brep_geographic_coordinate_system_info, # "convert": og_gs.convert_brep_coordinate_reference_system, # "create": og.create_brep_coordinate_system, # }, -# "object_type": model, -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_brep, -# "save_light_viewable": g_v.save_light_viewable_brep, -# "inspector": og_inspector.inspect_brep, # }, # "CrossSection": { -# "parent": "Section", -# "class": og_gs.CrossSection, -# "input_factory": og_gs.CrossSectionInputFactory, -# "output_factory": og_gs.CrossSectionOutputFactory, -# "additional_files": og_gs.cross_section_additional_files, -# "is_loadable": og_gs.is_cross_section_loadable, -# "object_priority": og_gs.cross_section_object_priority, -# "load": og_gs.load_cross_section, -# "is_saveable": og_gs.is_cross_section_saveable, -# "save": og_gs.save_cross_section, -# "builder": og_gs.CrossSectionBuilder, # "crs": { # "assign": og_gs.assign_section_geographic_coordinate_system_info, # "convert": og_gs.convert_section_coordinate_reference_system, # "create": og.create_section_coordinate_system, # }, -# "object_type": model, -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_cross_section, -# "save_light_viewable": g_v.save_light_viewable_cross_section, -# "inspector": og_inspector.inspect_section, # }, # "EdgedCurve2D": { -# "class": og.EdgedCurve2D, -# "input_factory": og.EdgedCurveInputFactory2D, -# "output_factory": og.EdgedCurveOutputFactory2D, -# "additional_files": og.edged_curve_additional_files2D, -# "is_loadable": og.is_edged_curve_loadable2D, -# "object_priority": og.edged_curve_object_priority2D, -# "load": og.load_edged_curve2D, -# "is_saveable": og.is_edged_curve_saveable2D, -# "save": og.save_edged_curve2D, -# "builder": og.EdgedCurveBuilder2D.create, # "crs": { # "assign": og_gs.assign_edged_curve_geographic_coordinate_system_info2D, # "convert": og_gs.convert_edged_curve_coordinate_reference_system2D, # "create": og.create_edged_curve_coordinate_system2D, # }, -# "object_type": mesh, -# "elements": [points, edges], -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_edged_curve2D, -# "save_light_viewable": g_v.save_light_viewable_edged_curve2D, -# "inspector": og_inspector.inspect_edged_curve2D, # }, # "EdgedCurve3D": { -# "class": og.EdgedCurve3D, -# "input_factory": og.EdgedCurveInputFactory3D, -# "output_factory": og.EdgedCurveOutputFactory3D, -# "additional_files": og.edged_curve_additional_files3D, -# "is_loadable": og.is_edged_curve_loadable3D, -# "object_priority": og.edged_curve_object_priority3D, -# "load": og.load_edged_curve3D, -# "is_saveable": og.is_edged_curve_saveable3D, -# "save": og.save_edged_curve3D, -# "builder": og.EdgedCurveBuilder3D.create, # "crs": { # "assign": og_gs.assign_edged_curve_geographic_coordinate_system_info3D, # "convert": og_gs.convert_edged_curve_coordinate_reference_system3D, # "create": og.create_edged_curve_coordinate_system3D, # }, -# "object_type": mesh, -# "elements": [points, edges], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_edged_curve3D, -# "save_light_viewable": g_v.save_light_viewable_edged_curve3D, -# "inspector": og_inspector.inspect_edged_curve3D, -# }, -# "Graph": { -# "class": og.Graph, -# "input_factory": og.GraphInputFactory, -# "output_factory": og.GraphOutputFactory, -# "additional_files": og.graph_additional_files, -# "is_loadable": og.is_graph_loadable, -# "object_priority": og.graph_object_priority, -# "load": og.load_graph, -# "is_saveable": og.is_graph_saveable, -# "save": og.save_graph, -# "builder": og.GraphBuilder.create, -# "object_type": mesh, -# "is_3D": False, -# "is_viewable": False, # }, # "HybridSolid3D": { # "class": og.HybridSolid3D, @@ -174,52 +83,18 @@ # "inspector": og_inspector.inspect_solid3D, # }, # "ImplicitCrossSection": { -# "parent": "CrossSection", -# "class": og_gs.ImplicitCrossSection, -# "input_factory": og_gs.ImplicitCrossSectionInputFactory, -# "output_factory": og_gs.ImplicitCrossSectionOutputFactory, -# "additional_files": og_gs.implicit_cross_section_additional_files, -# "is_loadable": og_gs.is_implicit_cross_section_loadable, -# "object_priority": og_gs.implicit_cross_section_object_priority, -# "load": og_gs.load_implicit_cross_section, -# "is_saveable": og_gs.is_implicit_cross_section_saveable, -# "save": og_gs.save_implicit_cross_section, -# "builder": og_gs.ImplicitCrossSectionBuilder, # "crs": { # "assign": og_gs.assign_section_geographic_coordinate_system_info, # "convert": og_gs.convert_section_coordinate_reference_system, # "create": og.create_section_coordinate_system, # }, -# "object_type": model, -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_implicit_cross_section, -# "save_light_viewable": g_v.save_light_viewable_implicit_cross_section, -# "inspector": og_inspector.inspect_section, # }, # "ImplicitStructuralModel": { -# "parent": "StructuralModel", -# "class": og_gs.ImplicitStructuralModel, -# "input_factory": og_gs.ImplicitStructuralModelInputFactory, -# "output_factory": og_gs.ImplicitStructuralModelOutputFactory, -# "additional_files": og_gs.implicit_structural_model_additional_files, -# "is_loadable": og_gs.is_implicit_structural_model_loadable, -# "object_priority": og_gs.implicit_structural_model_object_priority, -# "load": og_gs.load_implicit_structural_model, -# "is_saveable": og_gs.is_implicit_structural_model_saveable, -# "save": og_gs.save_implicit_structural_model, -# "builder": og_gs.ImplicitStructuralModelBuilder, # "crs": { # "assign": og_gs.assign_brep_geographic_coordinate_system_info, # "convert": og_gs.convert_brep_coordinate_reference_system, # "create": og.create_brep_coordinate_system, # }, -# "object_type": model, -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_implicit_structural_model, -# "save_light_viewable": g_v.save_light_viewable_implicit_structural_model, -# "inspector": og_inspector.inspect_brep, # }, # "LightRegularGrid2D": { # "class": og.LightRegularGrid2D, @@ -256,52 +131,18 @@ # "save_light_viewable": g_v.save_light_viewable_light_regular_grid3D, # }, # "PointSet2D": { -# "class": og.PointSet2D, -# "input_factory": og.PointSetInputFactory2D, -# "output_factory": og.PointSetOutputFactory2D, -# "additional_files": og.point_set_additional_files2D, -# "is_loadable": og.is_point_set_loadable2D, -# "object_priority": og.point_set_object_priority2D, -# "load": og.load_point_set2D, -# "is_saveable": og.is_point_set_saveable2D, -# "save": og.save_point_set2D, -# "builder": og.PointSetBuilder2D.create, # "crs": { # "assign": og_gs.assign_point_set_geographic_coordinate_system_info2D, # "convert": og_gs.convert_point_set_coordinate_reference_system2D, # "create": og.create_point_set_coordinate_system2D, # }, -# "object_type": mesh, -# "elements": [points], -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_point_set2D, -# "save_light_viewable": g_v.save_light_viewable_point_set2D, -# "inspector": og_inspector.inspect_point_set2D, # }, # "PointSet3D": { -# "class": og.PointSet3D, -# "input_factory": og.PointSetInputFactory3D, -# "output_factory": og.PointSetOutputFactory3D, -# "additional_files": og.point_set_additional_files3D, -# "is_loadable": og.is_point_set_loadable3D, -# "object_priority": og.point_set_object_priority3D, -# "load": og.load_point_set3D, -# "is_saveable": og.is_point_set_saveable3D, -# "save": og.save_point_set3D, -# "builder": og.PointSetBuilder3D.create, # "crs": { # "assign": og_gs.assign_point_set_geographic_coordinate_system_info3D, # "convert": og_gs.convert_point_set_coordinate_reference_system3D, # "create": og.create_point_set_coordinate_system3D, # }, -# "object_type": mesh, -# "elements": [points], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_point_set3D, -# "save_light_viewable": g_v.save_light_viewable_point_set3D, -# "inspector": og_inspector.inspect_point_set3D, # }, # "PolygonalSurface2D": { # "class": og.PolygonalSurface2D, @@ -375,36 +216,6 @@ # "save_light_viewable": g_v.save_light_viewable_polyhedral_solid3D, # "inspector": og_inspector.inspect_solid3D, # }, -# "RasterImage2D": { -# "class": og.RasterImage2D, -# "input_factory": og.RasterImageInputFactory2D, -# "output_factory": og.RasterImageOutputFactory2D, -# "additional_files": og.raster_image_additional_files2D, -# "is_loadable": og.is_raster_image_loadable2D, -# "object_priority": og.raster_image_object_priority2D, -# "load": og.load_raster_image2D, -# "is_saveable": og.is_raster_image_saveable2D, -# "save": og.save_raster_image2D, -# "object_type": mesh, -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_raster_image2D, -# }, -# "RasterImage3D": { -# "class": og.RasterImage3D, -# "input_factory": og.RasterImageInputFactory3D, -# "output_factory": og.RasterImageOutputFactory3D, -# "additional_files": og.raster_image_additional_files3D, -# "is_loadable": og.is_raster_image_loadable3D, -# "object_priority": og.raster_image_object_priority3D, -# "load": og.load_raster_image3D, -# "is_saveable": og.is_raster_image_saveable3D, -# "save": og.save_raster_image3D, -# "object_type": mesh, -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_raster_image3D, -# }, # "RegularGrid2D": { # "class": og.RegularGrid2D, # "input_factory": og.RegularGridInputFactory2D, @@ -452,51 +263,18 @@ # "save_light_viewable": g_v.save_light_viewable_regular_grid3D, # }, # "Section": { -# "class": og.Section, -# "input_factory": og.SectionInputFactory, -# "output_factory": og.SectionOutputFactory, -# "additional_files": og.section_additional_files, -# "is_loadable": og.is_section_loadable, -# "object_priority": og.section_object_priority, -# "load": og.load_section, -# "is_saveable": og.is_section_saveable, -# "save": og.save_section, -# "builder": og.SectionBuilder, # "crs": { # "assign": og_gs.assign_section_geographic_coordinate_system_info, # "convert": og_gs.convert_section_coordinate_reference_system, # "create": og.create_section_coordinate_system, # }, -# "object_type": model, -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_section, -# "save_light_viewable": g_v.save_light_viewable_section, -# "inspector": og_inspector.inspect_section, # }, # "StructuralModel": { -# "parent": "BRep", -# "class": og_gs.StructuralModel, -# "input_factory": og_gs.StructuralModelInputFactory, -# "output_factory": og_gs.StructuralModelOutputFactory, -# "additional_files": og_gs.structural_model_additional_files, -# "is_loadable": og_gs.is_structural_model_loadable, -# "object_priority": og_gs.structural_model_object_priority, -# "load": og_gs.load_structural_model, -# "is_saveable": og_gs.is_structural_model_saveable, -# "save": og_gs.save_structural_model, -# "builder": og_gs.StructuralModelBuilder, # "crs": { # "assign": og_gs.assign_brep_geographic_coordinate_system_info, # "convert": og_gs.convert_brep_coordinate_reference_system, # "create": og.create_brep_coordinate_system, # }, -# "object_type": model, -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_structural_model, -# "save_light_viewable": g_v.save_light_viewable_structural_model, -# "inspector": og_inspector.inspect_brep, # }, # "TetrahedralSolid3D": { # "class": og.TetrahedralSolid3D, @@ -570,19 +348,4 @@ # "save_light_viewable": g_v.save_light_viewable_triangulated_surface3D, # "inspector": og_inspector.inspect_surface3D, # }, -# "VertexSet": { -# "class": og.VertexSet, -# "input_factory": og.VertexSetInputFactory, -# "output_factory": og.VertexSetOutputFactory, -# "additional_files": og.vertex_set_additional_files, -# "is_loadable": og.is_vertex_set_loadable, -# "object_priority": og.vertex_set_object_priority, -# "load": og.load_vertex_set, -# "is_saveable": og.is_vertex_set_saveable, -# "save": og.save_vertex_set, -# "builder": og.VertexSetBuilder.create, -# "object_type": mesh, -# "is_3D": False, -# "is_viewable": False, -# }, # } diff --git a/src/opengeodeweb_back/geode_objects/geode_brep.py b/src/opengeodeweb_back/geode_objects/geode_brep.py index aade7514..e93422e7 100644 --- a/src/opengeodeweb_back/geode_objects/geode_brep.py +++ b/src/opengeodeweb_back/geode_objects/geode_brep.py @@ -3,11 +3,12 @@ # Third party imports import opengeode as og +import opengeode_geosciences as og_geosciences import opengeode_inspector as og_inspector import geode_viewables as viewables # Local application imports -from .types import GeodeModelType, ViewerType +from .types import GeodeModelType from .geode_model import GeodeModel, ComponentRegistry @@ -77,3 +78,25 @@ def mesh_components(self) -> ComponentRegistry: def inspect(self) -> og_inspector.BRepInspectionResult: return og_inspector.inspect_brep(self.brep) + + # def assign_crs( + # self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo3D + # ) -> None: + # builder = self.builder() + # og_geosciences.assign_brep_geographic_coordinate_system_info( + # self.brep, builder, crs_name, info + # ) + + # def convert_crs( + # self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo3D + # ) -> None: + # builder = self.builder() + # og_geosciences.convert_brep_coordinate_reference_system( + # self.brep, builder, crs_name, info + # ) + + # def create_crs( + # self, crs_name: str, input: og.CoordinateSystem2D, output: og.CoordinateSystem2D + # ) -> None: + # builder = self.builder() + # og.create_brep_coordinate_system(self.brep, builder, crs_name, input, output) diff --git a/src/opengeodeweb_back/geode_objects/geode_cross_section.py b/src/opengeodeweb_back/geode_objects/geode_cross_section.py new file mode 100644 index 00000000..8d81a28b --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_cross_section.py @@ -0,0 +1,75 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_geosciences as og_geosciences +import geode_viewables as viewables + +# Local application imports +from .types import GeodeModelType +from .geode_section import GeodeSection + + +class GeodeCrossSection(GeodeSection): + cross_section: og_geosciences.CrossSection + + def __init__( + self, cross_section: og_geosciences.CrossSection | None = None + ) -> None: + self.cross_section = ( + cross_section + if cross_section is not None + else og_geosciences.CrossSection() + ) + super().__init__(self.cross_section) + + @classmethod + def geode_model_type(cls) -> GeodeModelType: + return "CrossSection" + + def native_extension(self) -> str: + return self.cross_section.native_extension() + + def builder(self) -> og_geosciences.CrossSectionBuilder: + return og_geosciences.CrossSectionBuilder(self.cross_section) + + @classmethod + def load_model(cls, filename: str) -> GeodeCrossSection: + return GeodeCrossSection(og_geosciences.load_cross_section(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og_geosciences.cross_section_additional_files(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og_geosciences.is_cross_section_loadable(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og_geosciences.CrossSectionInputFactory.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og_geosciences.CrossSectionOutputFactory.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og_geosciences.cross_section_object_priority(filename) + + def is_saveable(self, filename: str) -> bool: + return og_geosciences.is_cross_section_saveable(self.cross_section, filename) + + def save(self, filename: str) -> list[str]: + return og_geosciences.save_cross_section(self.cross_section, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_cross_section( + self.cross_section, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_cross_section( + self.cross_section, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py b/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py new file mode 100644 index 00000000..4e9b8960 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py @@ -0,0 +1,80 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_graph import GeodeGraph + + +class GeodeEdgedCurve2D(GeodeGraph): + edged_curve: og.EdgedCurve2D + + def __init__(self, edged_curve: og.EdgedCurve2D | None = None) -> None: + self.edged_curve = edged_curve if edged_curve is not None else og.EdgedCurve2D() + super().__init__(self.edged_curve) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "EdgedCurve2D" + + def native_extension(self) -> str: + return self.edged_curve.native_extension() + + @classmethod + def is_3D(cls) -> bool: + return False + + @classmethod + def is_viewable(cls) -> bool: + return False + + def builder(self) -> og.EdgedCurveBuilder2D: + return og.EdgedCurveBuilder2D(self.edged_curve) + + @classmethod + def load_mesh(cls, filename: str) -> GeodeEdgedCurve2D: + return GeodeEdgedCurve2D(og.load_edged_curve2D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.edged_curve_additional_files2D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_edged_curve_loadable2D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.EdgedCurveInputFactory2D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.EdgedCurveOutputFactory2D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.edged_curve_object_priority2D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_edged_curve_saveable2D(self.edged_curve, filename) + + def save(self, filename: str) -> list[str]: + return og.save_edged_curve2D(self.edged_curve, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_edged_curve2D( + self.edged_curve, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_edged_curve2D( + self.edged_curve, filename_without_extension + ) + + def inspect(self) -> og_inspector.EdgedCurveInspectionResult: + return og_inspector.inspect_edged_curve2D(self.edged_curve) diff --git a/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py b/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py new file mode 100644 index 00000000..04047738 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py @@ -0,0 +1,80 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_graph import GeodeGraph + + +class GeodeEdgedCurve3D(GeodeGraph): + edged_curve: og.EdgedCurve3D + + def __init__(self, edged_curve: og.EdgedCurve3D | None = None) -> None: + self.edged_curve = edged_curve if edged_curve is not None else og.EdgedCurve3D() + super().__init__(self.edged_curve) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "EdgedCurve3D" + + def native_extension(self) -> str: + return self.edged_curve.native_extension() + + @classmethod + def is_3D(cls) -> bool: + return False + + @classmethod + def is_viewable(cls) -> bool: + return False + + def builder(self) -> og.EdgedCurveBuilder3D: + return og.EdgedCurveBuilder3D(self.edged_curve) + + @classmethod + def load_mesh(cls, filename: str) -> GeodeEdgedCurve3D: + return GeodeEdgedCurve3D(og.load_edged_curve3D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.edged_curve_additional_files3D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_edged_curve_loadable3D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.EdgedCurveInputFactory3D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.EdgedCurveOutputFactory3D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.edged_curve_object_priority3D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_edged_curve_saveable3D(self.edged_curve, filename) + + def save(self, filename: str) -> list[str]: + return og.save_edged_curve3D(self.edged_curve, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_edged_curve3D( + self.edged_curve, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_edged_curve3D( + self.edged_curve, filename_without_extension + ) + + def inspect(self) -> og_inspector.EdgedCurveInspectionResult: + return og_inspector.inspect_edged_curve3D(self.edged_curve) diff --git a/src/opengeodeweb_back/geode_objects/geode_graph.py b/src/opengeodeweb_back/geode_objects/geode_graph.py new file mode 100644 index 00000000..dc90b1a1 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_graph.py @@ -0,0 +1,76 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_vertex_set import GeodeVertexSet + + +class GeodeGraph(GeodeVertexSet): + graph: og.Graph + + def __init__(self, graph: og.Graph | None = None) -> None: + self.graph = graph if graph is not None else og.Graph() + super().__init__(self.graph) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "Graph" + + def native_extension(self) -> str: + return self.graph.native_extension() + + @classmethod + def is_3D(cls) -> bool: + return False + + @classmethod + def is_viewable(cls) -> bool: + return False + + def builder(self) -> og.GraphBuilder: + return og.GraphBuilder(self.graph) + + @classmethod + def load_mesh(cls, filename: str) -> GeodeGraph: + return GeodeGraph(og.load_graph(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.graph_additional_files(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_graph_loadable(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.GraphInputFactory.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.GraphOutputFactory.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.graph_object_priority(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_graph_saveable(self.graph, filename) + + def save(self, filename: str) -> list[str]: + return og.save_graph(self.graph, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return "" + + def save_light_viewable(self, filename_without_extension: str) -> str: + return "" + + def inspect(self) -> object: + return None diff --git a/src/opengeodeweb_back/geode_objects/geode_implicit_cross_section.py b/src/opengeodeweb_back/geode_objects/geode_implicit_cross_section.py new file mode 100644 index 00000000..05c9d8a7 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_implicit_cross_section.py @@ -0,0 +1,81 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_geosciences as og_geosciences +import geode_viewables as viewables + +# Local application imports +from .types import GeodeModelType +from .geode_cross_section import GeodeCrossSection + + +class GeodeImplicitCrossSection(GeodeCrossSection): + implicit_cross_section: og_geosciences.ImplicitCrossSection + + def __init__( + self, implicit_cross_section: og_geosciences.ImplicitCrossSection | None = None + ) -> None: + self.implicit_cross_section = ( + implicit_cross_section + if implicit_cross_section is not None + else og_geosciences.ImplicitCrossSection() + ) + super().__init__(self.implicit_cross_section) + + @classmethod + def geode_model_type(cls) -> GeodeModelType: + return "ImplicitCrossSection" + + def native_extension(self) -> str: + return self.implicit_cross_section.native_extension() + + def builder(self) -> og_geosciences.ImplicitCrossSectionBuilder: + return og_geosciences.ImplicitCrossSectionBuilder(self.implicit_cross_section) + + @classmethod + def load_model(cls, filename: str) -> GeodeImplicitCrossSection: + return GeodeImplicitCrossSection( + og_geosciences.load_implicit_cross_section(filename) + ) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og_geosciences.implicit_cross_section_additional_files(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og_geosciences.is_implicit_cross_section_loadable(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og_geosciences.ImplicitCrossSectionInputFactory.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og_geosciences.ImplicitCrossSectionOutputFactory.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og_geosciences.implicit_cross_section_object_priority(filename) + + def is_saveable(self, filename: str) -> bool: + return og_geosciences.is_implicit_cross_section_saveable( + self.implicit_cross_section, filename + ) + + def save(self, filename: str) -> list[str]: + return og_geosciences.save_implicit_cross_section( + self.implicit_cross_section, filename + ) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_implicit_cross_section( + self.implicit_cross_section, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_implicit_cross_section( + self.implicit_cross_section, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_implicit_structural_model.py b/src/opengeodeweb_back/geode_objects/geode_implicit_structural_model.py new file mode 100644 index 00000000..1adcdb02 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_implicit_structural_model.py @@ -0,0 +1,85 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_geosciences as og_geosciences +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeModelType +from .geode_structural_model import GeodeStructuralModel + + +class GeodeImplicitStructuralModel(GeodeStructuralModel): + implicit_structural_model: og_geosciences.ImplicitStructuralModel + + def __init__( + self, + implicit_structural_model: og_geosciences.ImplicitStructuralModel | None = None, + ) -> None: + self.implicit_structural_model = ( + implicit_structural_model + if implicit_structural_model is not None + else og_geosciences.ImplicitStructuralModel() + ) + super().__init__(self.implicit_structural_model) + + @classmethod + def geode_model_type(cls) -> GeodeModelType: + return "ImplicitStructuralModel" + + def native_extension(self) -> str: + return self.implicit_structural_model.native_extension() + + def builder(self) -> og_geosciences.ImplicitStructuralModelBuilder: + return og_geosciences.ImplicitStructuralModelBuilder( + self.implicit_structural_model + ) + + @classmethod + def load_model(cls, filename: str) -> GeodeImplicitStructuralModel: + return GeodeImplicitStructuralModel( + og_geosciences.load_implicit_structural_model(filename) + ) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og_geosciences.implicit_structural_model_additional_files(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og_geosciences.is_implicit_structural_model_loadable(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og_geosciences.ImplicitStructuralModelInputFactory.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og_geosciences.ImplicitStructuralModelOutputFactory.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og_geosciences.implicit_structural_model_object_priority(filename) + + def is_saveable(self, filename: str) -> bool: + return og_geosciences.is_implicit_structural_model_saveable( + self.implicit_structural_model, filename + ) + + def save(self, filename: str) -> list[str]: + return og_geosciences.save_implicit_structural_model( + self.implicit_structural_model, filename + ) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_implicit_structural_model( + self.implicit_structural_model, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_implicit_structural_model( + self.implicit_structural_model, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_point_set2d.py b/src/opengeodeweb_back/geode_objects/geode_point_set2d.py new file mode 100644 index 00000000..8f0eac52 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_point_set2d.py @@ -0,0 +1,80 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_vertex_set import GeodeVertexSet + + +class GeodePointSet2D(GeodeVertexSet): + point_set: og.PointSet2D + + def __init__(self, point_set: og.PointSet2D | None = None) -> None: + self.point_set = point_set if point_set is not None else og.PointSet2D() + super().__init__(self.point_set) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "PointSet2D" + + def native_extension(self) -> str: + return self.point_set.native_extension() + + @classmethod + def is_3D(cls) -> bool: + return False + + @classmethod + def is_viewable(cls) -> bool: + return True + + def builder(self) -> og.PointSetBuilder2D: + return og.PointSetBuilder2D(self.point_set) + + @classmethod + def load_mesh(cls, filename: str) -> GeodePointSet2D: + return GeodePointSet2D(og.load_point_set2D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.point_set_additional_files2D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_point_set_loadable2D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.PointSetInputFactory2D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.PointSetOutputFactory2D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.point_set_object_priority2D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_point_set_saveable2D(self.point_set, filename) + + def save(self, filename: str) -> list[str]: + return og.save_point_set2D(self.point_set, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_point_set2D( + self.point_set, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_point_set2D( + self.point_set, filename_without_extension + ) + + def inspect(self) -> og_inspector.PointSetInspectionResult: + return og_inspector.inspect_point_set2D(self.point_set) diff --git a/src/opengeodeweb_back/geode_objects/geode_point_set3d.py b/src/opengeodeweb_back/geode_objects/geode_point_set3d.py new file mode 100644 index 00000000..12d216b9 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_point_set3d.py @@ -0,0 +1,80 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_vertex_set import GeodeVertexSet + + +class GeodePointSet3D(GeodeVertexSet): + point_set: og.PointSet3D + + def __init__(self, point_set: og.PointSet3D | None = None) -> None: + self.point_set = point_set if point_set is not None else og.PointSet3D() + super().__init__(self.point_set) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "PointSet3D" + + def native_extension(self) -> str: + return self.point_set.native_extension() + + @classmethod + def is_3D(cls) -> bool: + return True + + @classmethod + def is_viewable(cls) -> bool: + return True + + def builder(self) -> og.PointSetBuilder3D: + return og.PointSetBuilder3D(self.point_set) + + @classmethod + def load_mesh(cls, filename: str) -> GeodePointSet3D: + return GeodePointSet3D(og.load_point_set3D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.point_set_additional_files3D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_point_set_loadable3D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.PointSetInputFactory3D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.PointSetOutputFactory3D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.point_set_object_priority3D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_point_set_saveable3D(self.point_set, filename) + + def save(self, filename: str) -> list[str]: + return og.save_point_set3D(self.point_set, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_point_set3D( + self.point_set, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_point_set3D( + self.point_set, filename_without_extension + ) + + def inspect(self) -> og_inspector.PointSetInspectionResult: + return og_inspector.inspect_point_set3D(self.point_set) diff --git a/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py b/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py new file mode 100644 index 00000000..8f5dbeac --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py @@ -0,0 +1,80 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_mesh import GeodeMesh + + +class GeodeRasterImage2D(GeodeMesh): + raster_image: og.RasterImage2D + + def __init__(self, raster_image: og.RasterImage2D) -> None: + self.raster_image = raster_image + super().__init__(self.raster_image) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "RasterImage2D" + + def native_extension(self) -> str: + return self.raster_image.native_extension() + + @classmethod + def is_3D(cls) -> bool: + return False + + @classmethod + def is_viewable(cls) -> bool: + return True + + def builder(self) -> None: + return None + + @classmethod + def load_mesh(cls, filename: str) -> GeodeRasterImage2D: + return GeodeRasterImage2D(og.load_raster_image2D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.raster_image_additional_files2D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_raster_image_loadable2D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.RasterImageInputFactory2D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.RasterImageOutputFactory2D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.raster_image_object_priority2D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_raster_image_saveable2D(self.raster_image, filename) + + def save(self, filename: str) -> list[str]: + return og.save_raster_image2D(self.raster_image, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_raster_image2D( + self.raster_image, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_raster_image2D( + self.raster_image, filename_without_extension + ) + + def inspect(self) -> None: + return None diff --git a/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py b/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py new file mode 100644 index 00000000..4ab772a0 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py @@ -0,0 +1,80 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_mesh import GeodeMesh + + +class GeodeRasterImage3D(GeodeMesh): + raster_image: og.RasterImage3D + + def __init__(self, raster_image: og.RasterImage3D) -> None: + self.raster_image = raster_image + super().__init__(self.raster_image) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "RasterImage3D" + + def native_extension(self) -> str: + return self.raster_image.native_extension() + + @classmethod + def is_3D(cls) -> bool: + return False + + @classmethod + def is_viewable(cls) -> bool: + return True + + def builder(self) -> None: + return None + + @classmethod + def load_mesh(cls, filename: str) -> GeodeRasterImage3D: + return GeodeRasterImage3D(og.load_raster_image3D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.raster_image_additional_files3D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_raster_image_loadable3D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.RasterImageInputFactory3D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.RasterImageOutputFactory3D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.raster_image_object_priority3D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_raster_image_saveable3D(self.raster_image, filename) + + def save(self, filename: str) -> list[str]: + return og.save_raster_image3D(self.raster_image, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_raster_image3D( + self.raster_image, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_raster_image3D( + self.raster_image, filename_without_extension + ) + + def inspect(self) -> None: + return None diff --git a/src/opengeodeweb_back/geode_objects/geode_section.py b/src/opengeodeweb_back/geode_objects/geode_section.py new file mode 100644 index 00000000..b31643b7 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_section.py @@ -0,0 +1,81 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeModelType, ViewerType +from .geode_model import GeodeModel, ComponentRegistry + + +class GeodeSection(GeodeModel): + section: og.Section + + def __init__(self, section: og.Section | None = None) -> None: + self.section = section if section is not None else og.Section() + super().__init__(self.section) + + @classmethod + def geode_model_type(cls) -> GeodeModelType: + return "Section" + + def native_extension(self) -> str: + return self.section.native_extension() + + @classmethod + def is_3D(cls) -> bool: + return False + + @classmethod + def is_viewable(cls) -> bool: + return True + + def builder(self) -> og.SectionBuilder: + return og.SectionBuilder(self.section) + + @classmethod + def load_model(cls, filename: str) -> GeodeSection: + return GeodeSection(og.load_section(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.section_additional_files(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_section_loadable(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.SectionInputFactory.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.SectionOutputFactory.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.section_object_priority(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_section_saveable(self.section, filename) + + def save(self, filename: str) -> list[str]: + return og.save_section(self.section, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_section(self.section, filename_without_extension) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_section( + self.section, filename_without_extension + ) + + def mesh_components(self) -> ComponentRegistry: + return self.section.mesh_components() + + def inspect(self) -> og_inspector.SectionInspectionResult: + return og_inspector.inspect_section(self.section) diff --git a/src/opengeodeweb_back/geode_objects/geode_structural_model.py b/src/opengeodeweb_back/geode_objects/geode_structural_model.py new file mode 100644 index 00000000..fa104f0d --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_structural_model.py @@ -0,0 +1,78 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_geosciences as og_geosciences +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeModelType +from .geode_brep import GeodeBRep + + +class GeodeStructuralModel(GeodeBRep): + structural_model: og_geosciences.StructuralModel + + def __init__( + self, structural_model: og_geosciences.StructuralModel | None = None + ) -> None: + self.structural_model = ( + structural_model + if structural_model is not None + else og_geosciences.StructuralModel() + ) + super().__init__(self.structural_model) + + @classmethod + def geode_model_type(cls) -> GeodeModelType: + return "StructuralModel" + + def native_extension(self) -> str: + return self.structural_model.native_extension() + + def builder(self) -> og_geosciences.StructuralModelBuilder: + return og_geosciences.StructuralModelBuilder(self.structural_model) + + @classmethod + def load_model(cls, filename: str) -> GeodeStructuralModel: + return GeodeStructuralModel(og_geosciences.load_structural_model(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og_geosciences.structural_model_additional_files(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og_geosciences.is_structural_model_loadable(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og_geosciences.StructuralModelInputFactory.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og_geosciences.StructuralModelOutputFactory.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og_geosciences.structural_model_object_priority(filename) + + def is_saveable(self, filename: str) -> bool: + return og_geosciences.is_structural_model_saveable( + self.structural_model, filename + ) + + def save(self, filename: str) -> list[str]: + return og_geosciences.save_structural_model(self.structural_model, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_structural_model( + self.structural_model, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_structural_model( + self.structural_model, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_vertex_set.py b/src/opengeodeweb_back/geode_objects/geode_vertex_set.py new file mode 100644 index 00000000..7c1a1a93 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_vertex_set.py @@ -0,0 +1,76 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType, ViewerType +from .geode_mesh import GeodeMesh + + +class GeodeVertexSet(GeodeMesh): + vertex_set: og.VertexSet + + def __init__(self, vertex_set: og.VertexSet | None = None) -> None: + self.vertex_set = vertex_set if vertex_set is not None else og.VertexSet() + super().__init__(self.vertex_set) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "VertexSet" + + def native_extension(self) -> str: + return self.vertex_set.native_extension() + + @classmethod + def is_3D(cls) -> bool: + return False + + @classmethod + def is_viewable(cls) -> bool: + return False + + def builder(self) -> og.VertexSetBuilder: + return og.VertexSetBuilder(self.vertex_set) + + @classmethod + def load_mesh(cls, filename: str) -> GeodeVertexSet: + return GeodeVertexSet(og.load_vertex_set(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.vertex_set_additional_files(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_vertex_set_loadable(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.VertexSetInputFactory.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.VertexSetOutputFactory.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.vertex_set_object_priority(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_vertex_set_saveable(self.vertex_set, filename) + + def save(self, filename: str) -> list[str]: + return og.save_vertex_set(self.vertex_set, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return "" + + def save_light_viewable(self, filename_without_extension: str) -> str: + return "" + + def inspect(self) -> object: + return None diff --git a/src/opengeodeweb_back/geode_objects/types.py b/src/opengeodeweb_back/geode_objects/types.py index f74c864e..a032f63b 100644 --- a/src/opengeodeweb_back/geode_objects/types.py +++ b/src/opengeodeweb_back/geode_objects/types.py @@ -7,8 +7,27 @@ GeodeSurfaceMeshType = Literal["PolygonalSurface3D"] -GeodeMeshType = Literal["VertexSet"] | GeodeSurfaceMeshType -GeodeModelType = Literal["BRep"] +GeodeMeshType = ( + Literal[ + "VertexSet", + "Graph", + "PointSet2D", + "PointSet3D", + "EdgeCurve2D", + "EdgeCurve3D", + "RasterImage2D", + "RasterImage3D", + ] + | GeodeSurfaceMeshType +) +GeodeModelType = Literal[ + "BRep", + "Section", + "StructuralModel", + "CrossSection", + "ImplicitStructuralModel", + "ImplicitCrossSection", +] GeodeObjectType = GeodeMeshType | GeodeModelType @@ -31,20 +50,24 @@ def _flatten_literal_args(literal: object) -> tuple[str, ...]: def geode_object_type(value: str) -> GeodeObjectType: if value not in GeodeObjectType_values: raise ValueError( - f"Invalid GeodeObjectType: {value!r}. Must be one of {allowed}" + f"Invalid GeodeObjectType: {value!r}. Must be one of {GeodeObjectType_values}" ) return cast(GeodeObjectType, value) def geode_mesh_type(value: str) -> GeodeMeshType: if value not in GeodeMeshType_values: - raise ValueError(f"Invalid GeodeMeshType: {value!r}. Must be one of {allowed}") + raise ValueError( + f"Invalid GeodeMeshType: {value!r}. Must be one of {GeodeMeshType_values}" + ) return cast(GeodeMeshType, value) def geode_model_type(value: str) -> GeodeModelType: if value not in GeodeModelType_values: - raise ValueError(f"Invalid GeodeModelType: {value!r}. Must be one of {allowed}") + raise ValueError( + f"Invalid GeodeModelType: {value!r}. Must be one of {GeodeModelType_values}" + ) return cast(GeodeModelType, value) From 53a5187a9ac241f75b7a5567a04b885755dc2396 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Fri, 21 Nov 2025 10:44:28 +0100 Subject: [PATCH 06/21] more geode objects --- requirements.in | 4 +- requirements.txt | 4 +- .../geode_objects/__init__.py | 379 +++--------------- .../geode_objects/geode_brep.py | 42 +- .../geode_objects/geode_edged_curve2d.py | 25 ++ .../geode_objects/geode_edged_curve3d.py | 27 +- .../geode_objects/geode_grid2d.py | 26 ++ .../geode_objects/geode_grid3d.py | 26 ++ .../geode_objects/geode_hybrid_solid3d.py | 71 ++++ .../geode_light_regular_grid2d.py | 66 +++ .../geode_light_regular_grid3d.py | 66 +++ .../geode_objects/geode_point_set2d.py | 25 ++ .../geode_objects/geode_point_set3d.py | 25 ++ .../geode_polygonal_surface2d.py | 73 ++++ .../geode_polygonal_surface3d.py | 73 ++++ .../geode_objects/geode_polyhedral_solid3d.py | 71 ++++ .../geode_objects/geode_raster_image3d.py | 2 +- .../geode_objects/geode_regulard_grid2d.py | 71 ++++ .../geode_objects/geode_regulard_grid3d.py | 71 ++++ .../geode_objects/geode_section.py | 25 ++ .../geode_objects/geode_solid_mesh3d.py | 58 +++ .../geode_objects/geode_surface_mesh2d.py | 60 +++ .../geode_objects/geode_surface_mesh3d.py | 60 +++ .../geode_tetrahedral_solid3d.py | 73 ++++ .../geode_triangulated_surface2d.py | 77 ++++ .../geode_triangulated_surface3d.py | 77 ++++ src/opengeodeweb_back/geode_objects/types.py | 42 +- src/opengeodeweb_back/utils_functions.py | 41 +- 28 files changed, 1286 insertions(+), 374 deletions(-) create mode 100644 src/opengeodeweb_back/geode_objects/geode_grid2d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_grid3d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_hybrid_solid3d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_polygonal_surface2d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_polygonal_surface3d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_polyhedral_solid3d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_regulard_grid3d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_solid_mesh3d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_surface_mesh2d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_surface_mesh3d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_tetrahedral_solid3d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_triangulated_surface2d.py create mode 100644 src/opengeodeweb_back/geode_objects/geode_triangulated_surface3d.py diff --git a/requirements.in b/requirements.in index 77597074..68044040 100644 --- a/requirements.in +++ b/requirements.in @@ -1,7 +1,7 @@ -opengeode-core==15.30.2 +opengeode-core==15.30.3 opengeode-io==7.4.6 opengeode-inspector==6.8.6 -opengeode-geosciences==9.5.4 +opengeode-geosciences==9.5.5 opengeode-geosciencesio==5.8.6 geode-common==33.11.3 geode-viewables==3.3.2 diff --git a/requirements.txt b/requirements.txt index 78173de7..d293d980 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,7 +31,7 @@ markupsafe>=3 # flask # jinja2 # werkzeug -opengeode-core==15.30.2 +opengeode-core==15.30.3 # via # -r requirements.in # geode-common @@ -40,7 +40,7 @@ opengeode-core==15.30.2 # opengeode-geosciencesio # opengeode-inspector # opengeode-io -opengeode-geosciences==9.5.4 +opengeode-geosciences==9.5.5 # via # -r requirements.in # geode-viewables diff --git a/src/opengeodeweb_back/geode_objects/__init__.py b/src/opengeodeweb_back/geode_objects/__init__.py index 93824919..fa7cc64e 100644 --- a/src/opengeodeweb_back/geode_objects/__init__.py +++ b/src/opengeodeweb_back/geode_objects/__init__.py @@ -17,335 +17,62 @@ from .geode_model import GeodeModel from .geode_mesh import GeodeMesh from .geode_brep import GeodeBRep +from .geode_vertex_set import GeodeVertexSet +from .geode_graph import GeodeGraph +from .geode_point_set2d import GeodePointSet2D +from .geode_point_set3d import GeodePointSet3D +from .geode_edged_curve2d import GeodeEdgedCurve2D +from .geode_edged_curve3d import GeodeEdgedCurve3D +from .geode_raster_image2d import GeodeRasterImage2D +from .geode_raster_image3d import GeodeRasterImage3D +from .geode_polygonal_surface2d import GeodePolygonalSurface2D +from .geode_polygonal_surface3d import GeodePolygonalSurface3D +from .geode_triangulated_surface2d import GeodeTriangulatedSurface2D +from .geode_triangulated_surface3d import GeodeTriangulatedSurface3D +from .geode_regulard_grid2d import GeodeRegularGrid2D +from .geode_polyhedral_solid3d import GeodePolyhedralSolid3D +from .geode_tetrahedral_solid3d import GeodeTetrahedralSolid3D +from .geode_hybrid_solid3d import GeodeHybridSolid3D +from .geode_regulard_grid3d import GeodeRegularGrid3D +from .geode_light_regular_grid2d import GeodeLightRegularGrid2D +from .geode_light_regular_grid3d import GeodeLightRegularGrid3D +from .geode_section import GeodeSection +from .geode_structural_model import GeodeStructuralModel +from .geode_cross_section import GeodeCrossSection +from .geode_implicit_structural_model import GeodeImplicitStructuralModel +from .geode_implicit_cross_section import GeodeImplicitCrossSection - -geode_meshes: dict[GeodeMeshType, type[GeodeMesh]] = {} -geode_models: dict[GeodeModelType, type[GeodeModel]] = {"BRep": GeodeBRep} +geode_meshes: dict[GeodeMeshType, type[GeodeMesh]] = { + "VertexSet": GeodeVertexSet, + "Graph": GeodeGraph, + "PointSet2D": GeodePointSet2D, + "PointSet3D": GeodePointSet3D, + "EdgedCurve2D": GeodeEdgedCurve2D, + "EdgedCurve3D": GeodeEdgedCurve3D, + "RasterImage2D": GeodeRasterImage2D, + "RasterImage3D": GeodeRasterImage3D, + "PolygonalSurface2D": GeodePolygonalSurface2D, + "PolygonalSurface3D": GeodePolygonalSurface3D, + "TriangulatedSurface2D": GeodeTriangulatedSurface2D, + "TriangulatedSurface3D": GeodeTriangulatedSurface3D, + "RegularGrid2D": GeodeRegularGrid2D, + "PolyhedralSolid3D": GeodePolyhedralSolid3D, + "TetrahedralSolid3D": GeodeTetrahedralSolid3D, + "HybridSolid3D": GeodeHybridSolid3D, + "RegularGrid3D": GeodeRegularGrid3D, + "LightRegularGrid2D": GeodeLightRegularGrid2D, + "LightRegularGrid3D": GeodeLightRegularGrid3D, +} +geode_models: dict[GeodeModelType, type[GeodeModel]] = { + "BRep": GeodeBRep, + "Section": GeodeSection, + "StructuralModel": GeodeStructuralModel, + "CrossSection": GeodeCrossSection, + "ImplicitStructuralModel": GeodeImplicitStructuralModel, + "ImplicitCrossSection": GeodeImplicitCrossSection, +} GeodeObjectsDict = dict[GeodeObjectType, type[GeodeObject]] geode_objects: GeodeObjectsDict = {} geode_objects.update(cast(GeodeObjectsDict, geode_meshes)) geode_objects.update(cast(GeodeObjectsDict, geode_models)) - - -# def geode_objects_dict(): -# return { -# "BRep": { -# "crs": { -# "assign": og_gs.assign_brep_geographic_coordinate_system_info, -# "convert": og_gs.convert_brep_coordinate_reference_system, -# "create": og.create_brep_coordinate_system, -# }, -# }, -# "CrossSection": { -# "crs": { -# "assign": og_gs.assign_section_geographic_coordinate_system_info, -# "convert": og_gs.convert_section_coordinate_reference_system, -# "create": og.create_section_coordinate_system, -# }, -# }, -# "EdgedCurve2D": { -# "crs": { -# "assign": og_gs.assign_edged_curve_geographic_coordinate_system_info2D, -# "convert": og_gs.convert_edged_curve_coordinate_reference_system2D, -# "create": og.create_edged_curve_coordinate_system2D, -# }, -# }, -# "EdgedCurve3D": { -# "crs": { -# "assign": og_gs.assign_edged_curve_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_edged_curve_coordinate_reference_system3D, -# "create": og.create_edged_curve_coordinate_system3D, -# }, -# }, -# "HybridSolid3D": { -# "class": og.HybridSolid3D, -# "input_factory": og.HybridSolidInputFactory3D, -# "output_factory": og.HybridSolidOutputFactory3D, -# "additional_files": og.hybrid_solid_additional_files3D, -# "is_loadable": og.is_hybrid_solid_loadable3D, -# "object_priority": og.hybrid_solid_object_priority3D, -# "load": og.load_hybrid_solid3D, -# "is_saveable": og.is_hybrid_solid_saveable3D, -# "save": og.save_hybrid_solid3D, -# "builder": og.HybridSolidBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, -# "create": og.create_solid_mesh_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points, polyhedrons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_hybrid_solid3D, -# "save_light_viewable": g_v.save_light_viewable_hybrid_solid3D, -# "inspector": og_inspector.inspect_solid3D, -# }, -# "ImplicitCrossSection": { -# "crs": { -# "assign": og_gs.assign_section_geographic_coordinate_system_info, -# "convert": og_gs.convert_section_coordinate_reference_system, -# "create": og.create_section_coordinate_system, -# }, -# }, -# "ImplicitStructuralModel": { -# "crs": { -# "assign": og_gs.assign_brep_geographic_coordinate_system_info, -# "convert": og_gs.convert_brep_coordinate_reference_system, -# "create": og.create_brep_coordinate_system, -# }, -# }, -# "LightRegularGrid2D": { -# "class": og.LightRegularGrid2D, -# "input_factory": og.LightRegularGridInputFactory2D, -# "output_factory": og.LightRegularGridOutputFactory2D, -# "additional_files": og.light_regular_grid_additional_files2D, -# "is_loadable": og.is_light_regular_grid_loadable2D, -# "object_priority": og.light_regular_grid_object_priority2D, -# "load": og.load_light_regular_grid2D, -# "is_saveable": og.is_light_regular_grid_saveable2D, -# "save": og.save_light_regular_grid2D, -# "object_type": mesh, -# "elements": [points, polygons], -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_light_regular_grid2D, -# "save_light_viewable": g_v.save_light_viewable_light_regular_grid2D, -# }, -# "LightRegularGrid3D": { -# "class": og.LightRegularGrid3D, -# "input_factory": og.LightRegularGridInputFactory3D, -# "output_factory": og.LightRegularGridOutputFactory3D, -# "additional_files": og.light_regular_grid_additional_files3D, -# "is_loadable": og.is_light_regular_grid_loadable3D, -# "object_priority": og.light_regular_grid_object_priority3D, -# "load": og.load_light_regular_grid3D, -# "is_saveable": og.is_light_regular_grid_saveable3D, -# "save": og.save_light_regular_grid3D, -# "object_type": mesh, -# "elements": [points, polyhedrons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_light_regular_grid3D, -# "save_light_viewable": g_v.save_light_viewable_light_regular_grid3D, -# }, -# "PointSet2D": { -# "crs": { -# "assign": og_gs.assign_point_set_geographic_coordinate_system_info2D, -# "convert": og_gs.convert_point_set_coordinate_reference_system2D, -# "create": og.create_point_set_coordinate_system2D, -# }, -# }, -# "PointSet3D": { -# "crs": { -# "assign": og_gs.assign_point_set_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_point_set_coordinate_reference_system3D, -# "create": og.create_point_set_coordinate_system3D, -# }, -# }, -# "PolygonalSurface2D": { -# "class": og.PolygonalSurface2D, -# "input_factory": og.PolygonalSurfaceInputFactory2D, -# "output_factory": og.PolygonalSurfaceOutputFactory2D, -# "additional_files": og.polygonal_surface_additional_files2D, -# "is_loadable": og.is_polygonal_surface_loadable2D, -# "object_priority": og.polygonal_surface_object_priority2D, -# "load": og.load_polygonal_surface2D, -# "is_saveable": og.is_polygonal_surface_saveable2D, -# "save": og.save_polygonal_surface2D, -# "builder": og.PolygonalSurfaceBuilder2D.create, -# "crs": { -# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, -# "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, -# "create": og.create_surface_mesh_coordinate_system2D, -# }, -# "object_type": mesh, -# "elements": [points, polygons], -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_polygonal_surface2D, -# "save_light_viewable": g_v.save_light_viewable_polygonal_surface2D, -# "inspector": og_inspector.inspect_surface2D, -# }, -# "PolygonalSurface3D": { -# "class": og.PolygonalSurface3D, -# "input_factory": og.PolygonalSurfaceInputFactory3D, -# "output_factory": og.PolygonalSurfaceOutputFactory3D, -# "additional_files": og.polygonal_surface_additional_files3D, -# "is_loadable": og.is_polygonal_surface_loadable3D, -# "object_priority": og.polygonal_surface_object_priority3D, -# "load": og.load_polygonal_surface3D, -# "is_saveable": og.is_polygonal_surface_saveable3D, -# "save": og.save_polygonal_surface3D, -# "builder": og.PolygonalSurfaceBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_surface_mesh_coordinate_reference_system3D, -# "create": og.create_surface_mesh_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points, polygons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_polygonal_surface3D, -# "save_light_viewable": g_v.save_light_viewable_polygonal_surface3D, -# "inspector": og_inspector.inspect_surface3D, -# }, -# "PolyhedralSolid3D": { -# "class": og.PolyhedralSolid3D, -# "input_factory": og.PolyhedralSolidInputFactory3D, -# "output_factory": og.PolyhedralSolidOutputFactory3D, -# "additional_files": og.polyhedral_solid_additional_files3D, -# "is_loadable": og.is_polyhedral_solid_loadable3D, -# "object_priority": og.polyhedral_solid_object_priority3D, -# "load": og.load_polyhedral_solid3D, -# "is_saveable": og.is_polyhedral_solid_saveable3D, -# "save": og.save_polyhedral_solid3D, -# "builder": og.PolyhedralSolidBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, -# "create": og.create_solid_mesh_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points, polyhedrons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_polyhedral_solid3D, -# "save_light_viewable": g_v.save_light_viewable_polyhedral_solid3D, -# "inspector": og_inspector.inspect_solid3D, -# }, -# "RegularGrid2D": { -# "class": og.RegularGrid2D, -# "input_factory": og.RegularGridInputFactory2D, -# "output_factory": og.RegularGridOutputFactory2D, -# "additional_files": og.regular_grid_additional_files2D, -# "is_loadable": og.is_regular_grid_loadable2D, -# "object_priority": og.regular_grid_object_priority2D, -# "load": og.load_regular_grid2D, -# "is_saveable": og.is_regular_grid_saveable2D, -# "save": og.save_regular_grid2D, -# "builder": og.RegularGridBuilder2D.create, -# "crs": { -# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, -# "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, -# "create": og.create_surface_mesh_coordinate_system2D, -# }, -# "object_type": mesh, -# "elements": [points, polygons], -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_regular_grid2D, -# "save_light_viewable": g_v.save_light_viewable_regular_grid2D, -# }, -# "RegularGrid3D": { -# "class": og.RegularGrid3D, -# "input_factory": og.RegularGridInputFactory3D, -# "output_factory": og.RegularGridOutputFactory3D, -# "additional_files": og.regular_grid_additional_files3D, -# "is_loadable": og.is_regular_grid_loadable3D, -# "object_priority": og.regular_grid_object_priority3D, -# "load": og.load_regular_grid3D, -# "is_saveable": og.is_regular_grid_saveable3D, -# "save": og.save_regular_grid3D, -# "builder": og.RegularGridBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, -# "create": og.create_surface_mesh_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points, polyhedrons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_regular_grid3D, -# "save_light_viewable": g_v.save_light_viewable_regular_grid3D, -# }, -# "Section": { -# "crs": { -# "assign": og_gs.assign_section_geographic_coordinate_system_info, -# "convert": og_gs.convert_section_coordinate_reference_system, -# "create": og.create_section_coordinate_system, -# }, -# }, -# "StructuralModel": { -# "crs": { -# "assign": og_gs.assign_brep_geographic_coordinate_system_info, -# "convert": og_gs.convert_brep_coordinate_reference_system, -# "create": og.create_brep_coordinate_system, -# }, -# }, -# "TetrahedralSolid3D": { -# "class": og.TetrahedralSolid3D, -# "input_factory": og.TetrahedralSolidInputFactory3D, -# "output_factory": og.TetrahedralSolidOutputFactory3D, -# "additional_files": og.tetrahedral_solid_additional_files3D, -# "is_loadable": og.is_tetrahedral_solid_loadable3D, -# "object_priority": og.tetrahedral_solid_object_priority3D, -# "load": og.load_tetrahedral_solid3D, -# "is_saveable": og.is_tetrahedral_solid_saveable3D, -# "save": og.save_tetrahedral_solid3D, -# "builder": og.TetrahedralSolidBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, -# "create": og.create_solid_mesh_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points, polyhedrons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_tetrahedral_solid3D, -# "save_light_viewable": g_v.save_light_viewable_tetrahedral_solid3D, -# "inspector": og_inspector.inspect_solid3D, -# }, -# "TriangulatedSurface2D": { -# "class": og.TriangulatedSurface2D, -# "input_factory": og.TriangulatedSurfaceInputFactory2D, -# "output_factory": og.TriangulatedSurfaceOutputFactory2D, -# "additional_files": og.triangulated_surface_additional_files2D, -# "is_loadable": og.is_triangulated_surface_loadable2D, -# "object_priority": og.triangulated_surface_object_priority2D, -# "load": og.load_triangulated_surface2D, -# "is_saveable": og.is_triangulated_surface_saveable2D, -# "save": og.save_triangulated_surface2D, -# "builder": og.TriangulatedSurfaceBuilder2D.create, -# "crs": { -# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, -# "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, -# "create": og.create_surface_mesh_coordinate_system2D, -# }, -# "object_type": mesh, -# "elements": [points, polygons], -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_triangulated_surface2D, -# "save_light_viewable": g_v.save_light_viewable_triangulated_surface2D, -# "inspector": og_inspector.inspect_surface2D, -# }, -# "TriangulatedSurface3D": { -# "class": og.TriangulatedSurface3D, -# "input_factory": og.TriangulatedSurfaceInputFactory3D, -# "output_factory": og.TriangulatedSurfaceOutputFactory3D, -# "additional_files": og.triangulated_surface_additional_files3D, -# "is_loadable": og.is_triangulated_surface_loadable3D, -# "object_priority": og.triangulated_surface_object_priority3D, -# "load": og.load_triangulated_surface3D, -# "is_saveable": og.is_triangulated_surface_saveable3D, -# "save": og.save_triangulated_surface3D, -# "builder": og.TriangulatedSurfaceBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_surface_mesh_coordinate_reference_system3D, -# "create": og.create_surface_mesh_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points, polygons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_triangulated_surface3D, -# "save_light_viewable": g_v.save_light_viewable_triangulated_surface3D, -# "inspector": og_inspector.inspect_surface3D, -# }, -# } diff --git a/src/opengeodeweb_back/geode_objects/geode_brep.py b/src/opengeodeweb_back/geode_objects/geode_brep.py index e93422e7..a86bbf3f 100644 --- a/src/opengeodeweb_back/geode_objects/geode_brep.py +++ b/src/opengeodeweb_back/geode_objects/geode_brep.py @@ -79,24 +79,24 @@ def mesh_components(self) -> ComponentRegistry: def inspect(self) -> og_inspector.BRepInspectionResult: return og_inspector.inspect_brep(self.brep) - # def assign_crs( - # self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo3D - # ) -> None: - # builder = self.builder() - # og_geosciences.assign_brep_geographic_coordinate_system_info( - # self.brep, builder, crs_name, info - # ) - - # def convert_crs( - # self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo3D - # ) -> None: - # builder = self.builder() - # og_geosciences.convert_brep_coordinate_reference_system( - # self.brep, builder, crs_name, info - # ) - - # def create_crs( - # self, crs_name: str, input: og.CoordinateSystem2D, output: og.CoordinateSystem2D - # ) -> None: - # builder = self.builder() - # og.create_brep_coordinate_system(self.brep, builder, crs_name, input, output) + def assign_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.assign_brep_geographic_coordinate_system_info( + self.brep, builder, crs_name, info + ) + + def convert_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.convert_brep_coordinate_reference_system( + self.brep, builder, crs_name, info + ) + + def create_crs( + self, crs_name: str, input: og.CoordinateSystem2D, output: og.CoordinateSystem2D + ) -> None: + builder = self.builder() + og.create_brep_coordinate_system(self.brep, builder, crs_name, input, output) diff --git a/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py b/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py index 4e9b8960..143d2df3 100644 --- a/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py @@ -3,6 +3,7 @@ # Third party imports import opengeode as og +import opengeode_geosciences as og_geosciences import opengeode_inspector as og_inspector import geode_viewables as viewables @@ -78,3 +79,27 @@ def save_light_viewable(self, filename_without_extension: str) -> str: def inspect(self) -> og_inspector.EdgedCurveInspectionResult: return og_inspector.inspect_edged_curve2D(self.edged_curve) + + def assign_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.assign_edged_curve_geographic_coordinate_system_info2D( + self.edged_curve, builder, crs_name, info + ) + + def convert_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.convert_edged_curve_coordinate_reference_system2D( + self.edged_curve, builder, crs_name, info + ) + + def create_crs( + self, crs_name: str, input: og.CoordinateSystem2D, output: og.CoordinateSystem2D + ) -> None: + builder = self.builder() + og.create_edged_curve_coordinate_system2D( + self.edged_curve, builder, crs_name, input, output + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py b/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py index 04047738..017608ab 100644 --- a/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py @@ -3,6 +3,7 @@ # Third party imports import opengeode as og +import opengeode_geosciences as og_geosciences import opengeode_inspector as og_inspector import geode_viewables as viewables @@ -27,7 +28,7 @@ def native_extension(self) -> str: @classmethod def is_3D(cls) -> bool: - return False + return True @classmethod def is_viewable(cls) -> bool: @@ -78,3 +79,27 @@ def save_light_viewable(self, filename_without_extension: str) -> str: def inspect(self) -> og_inspector.EdgedCurveInspectionResult: return og_inspector.inspect_edged_curve3D(self.edged_curve) + + def assign_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.assign_edged_curve_geographic_coordinate_system_info3D( + self.edged_curve, builder, crs_name, info + ) + + def convert_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.convert_edged_curve_coordinate_reference_system3D( + self.edged_curve, builder, crs_name, info + ) + + def create_crs( + self, crs_name: str, input: og.CoordinateSystem2D, output: og.CoordinateSystem2D + ) -> None: + builder = self.builder() + og.create_edged_curve_coordinate_system3D( + self.edged_curve, builder, crs_name, input, output + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_grid2d.py b/src/opengeodeweb_back/geode_objects/geode_grid2d.py new file mode 100644 index 00000000..c7b6d4d2 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_grid2d.py @@ -0,0 +1,26 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_mesh import GeodeMesh + + +class GeodeGrid2D(GeodeMesh): + @classmethod + def is_3D(cls) -> bool: + return False + + @classmethod + def is_viewable(cls) -> bool: + return True + + def builder(self) -> None: + return None + + def inspect(self) -> None: + return None diff --git a/src/opengeodeweb_back/geode_objects/geode_grid3d.py b/src/opengeodeweb_back/geode_objects/geode_grid3d.py new file mode 100644 index 00000000..9f8c6730 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_grid3d.py @@ -0,0 +1,26 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_mesh import GeodeMesh + + +class GeodeGrid3D(GeodeMesh): + @classmethod + def is_3D(cls) -> bool: + return True + + @classmethod + def is_viewable(cls) -> bool: + return True + + def builder(self) -> None: + return None + + def inspect(self) -> None: + return None diff --git a/src/opengeodeweb_back/geode_objects/geode_hybrid_solid3d.py b/src/opengeodeweb_back/geode_objects/geode_hybrid_solid3d.py new file mode 100644 index 00000000..5cef1e34 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_hybrid_solid3d.py @@ -0,0 +1,71 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_solid_mesh3d import GeodeSolidMesh3D + + +class GeodeHybridSolid3D(GeodeSolidMesh3D): + hybrid_solid: og.HybridSolid3D + + def __init__(self, hybrid_solid: og.HybridSolid3D | None = None) -> None: + self.hybrid_solid = ( + hybrid_solid if hybrid_solid is not None else og.HybridSolid3D() + ) + super().__init__(self.hybrid_solid) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "HybridSolid3D" + + def native_extension(self) -> str: + return self.hybrid_solid.native_extension() + + def builder(self) -> og.HybridSolidBuilder3D: + return og.HybridSolidBuilder3D(self.hybrid_solid) + + @classmethod + def load_mesh(cls, filename: str) -> GeodeHybridSolid3D: + return GeodeHybridSolid3D(og.load_hybrid_solid3D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.hybrid_solid_additional_files3D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_hybrid_solid_loadable3D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.HybridSolidInputFactory3D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.HybridSolidOutputFactory3D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.hybrid_solid_object_priority3D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_hybrid_solid_saveable3D(self.hybrid_solid, filename) + + def save(self, filename: str) -> list[str]: + return og.save_hybrid_solid3D(self.hybrid_solid, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_hybrid_solid3D( + self.hybrid_solid, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_hybrid_solid3D( + self.hybrid_solid, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py new file mode 100644 index 00000000..071c8631 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py @@ -0,0 +1,66 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_grid2d import GeodeGrid2D + + +class GeodeLightRegularGrid2D(GeodeGrid2D): + light_regular_grid: og.LightRegularGrid2D + + def __init__(self, light_regular_grid: og.LightRegularGrid2D) -> None: + self.light_regular_grid = light_regular_grid + super().__init__(self.light_regular_grid) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "LightRegularGrid2D" + + def native_extension(self) -> str: + return self.light_regular_grid.native_extension() + + @classmethod + def load_mesh(cls, filename: str) -> GeodeLightRegularGrid2D: + return GeodeLightRegularGrid2D(og.load_light_regular_grid2D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.light_regular_grid_additional_files2D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_light_regular_grid_loadable2D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.LightRegularGridInputFactory2D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.LightRegularGridOutputFactory2D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.light_regular_grid_object_priority2D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_light_regular_grid_saveable2D(self.light_regular_grid, filename) + + def save(self, filename: str) -> list[str]: + return og.save_light_regular_grid2D(self.light_regular_grid, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_light_regular_grid2D( + self.light_regular_grid, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_light_regular_grid2D( + self.light_regular_grid, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py new file mode 100644 index 00000000..dfb43f1c --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py @@ -0,0 +1,66 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_grid3d import GeodeGrid3D + + +class GeodeLightRegularGrid3D(GeodeGrid3D): + light_regular_grid: og.LightRegularGrid3D + + def __init__(self, light_regular_grid: og.LightRegularGrid3D) -> None: + self.light_regular_grid = light_regular_grid + super().__init__(self.light_regular_grid) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "LightRegularGrid3D" + + def native_extension(self) -> str: + return self.light_regular_grid.native_extension() + + @classmethod + def load_mesh(cls, filename: str) -> GeodeLightRegularGrid3D: + return GeodeLightRegularGrid3D(og.load_light_regular_grid3D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.light_regular_grid_additional_files3D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_light_regular_grid_loadable3D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.LightRegularGridInputFactory3D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.LightRegularGridOutputFactory3D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.light_regular_grid_object_priority3D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_light_regular_grid_saveable3D(self.light_regular_grid, filename) + + def save(self, filename: str) -> list[str]: + return og.save_light_regular_grid3D(self.light_regular_grid, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_light_regular_grid3D( + self.light_regular_grid, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_light_regular_grid3D( + self.light_regular_grid, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_point_set2d.py b/src/opengeodeweb_back/geode_objects/geode_point_set2d.py index 8f0eac52..87c04724 100644 --- a/src/opengeodeweb_back/geode_objects/geode_point_set2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_point_set2d.py @@ -3,6 +3,7 @@ # Third party imports import opengeode as og +import opengeode_geosciences as og_geosciences import opengeode_inspector as og_inspector import geode_viewables as viewables @@ -78,3 +79,27 @@ def save_light_viewable(self, filename_without_extension: str) -> str: def inspect(self) -> og_inspector.PointSetInspectionResult: return og_inspector.inspect_point_set2D(self.point_set) + + def assign_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.assign_point_set_geographic_coordinate_system_info2D( + self.point_set, builder, crs_name, info + ) + + def convert_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.convert_point_set_coordinate_reference_system2D( + self.point_set, builder, crs_name, info + ) + + def create_crs( + self, crs_name: str, input: og.CoordinateSystem2D, output: og.CoordinateSystem2D + ) -> None: + builder = self.builder() + og.create_point_set_coordinate_system2D( + self.point_set, builder, crs_name, input, output + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_point_set3d.py b/src/opengeodeweb_back/geode_objects/geode_point_set3d.py index 12d216b9..d2e1b921 100644 --- a/src/opengeodeweb_back/geode_objects/geode_point_set3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_point_set3d.py @@ -3,6 +3,7 @@ # Third party imports import opengeode as og +import opengeode_geosciences as og_geosciences import opengeode_inspector as og_inspector import geode_viewables as viewables @@ -78,3 +79,27 @@ def save_light_viewable(self, filename_without_extension: str) -> str: def inspect(self) -> og_inspector.PointSetInspectionResult: return og_inspector.inspect_point_set3D(self.point_set) + + def assign_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.assign_point_set_geographic_coordinate_system_info3D( + self.point_set, builder, crs_name, info + ) + + def convert_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.convert_point_set_coordinate_reference_system3D( + self.point_set, builder, crs_name, info + ) + + def create_crs( + self, crs_name: str, input: og.CoordinateSystem2D, output: og.CoordinateSystem2D + ) -> None: + builder = self.builder() + og.create_point_set_coordinate_system3D( + self.point_set, builder, crs_name, input, output + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_polygonal_surface2d.py b/src/opengeodeweb_back/geode_objects/geode_polygonal_surface2d.py new file mode 100644 index 00000000..899d5541 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_polygonal_surface2d.py @@ -0,0 +1,73 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_surface_mesh2d import GeodeSurfaceMesh2D + + +class GeodePolygonalSurface2D(GeodeSurfaceMesh2D): + polygonal_surface: og.PolygonalSurface2D + + def __init__(self, polygonal_surface: og.PolygonalSurface2D | None = None) -> None: + self.polygonal_surface = ( + polygonal_surface + if polygonal_surface is not None + else og.PolygonalSurface2D() + ) + super().__init__(self.polygonal_surface) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "PolygonalSurface2D" + + def native_extension(self) -> str: + return self.polygonal_surface.native_extension() + + def builder(self) -> og.PolygonalSurfaceBuilder2D: + return og.PolygonalSurfaceBuilder2D(self.polygonal_surface) + + @classmethod + def load_mesh(cls, filename: str) -> GeodePolygonalSurface2D: + return GeodePolygonalSurface2D(og.load_polygonal_surface2D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.polygonal_surface_additional_files2D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_polygonal_surface_loadable2D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.PolygonalSurfaceInputFactory2D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.PolygonalSurfaceOutputFactory2D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.polygonal_surface_object_priority2D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_polygonal_surface_saveable2D(self.polygonal_surface, filename) + + def save(self, filename: str) -> list[str]: + return og.save_polygonal_surface2D(self.polygonal_surface, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_polygonal_surface2D( + self.polygonal_surface, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_polygonal_surface2D( + self.polygonal_surface, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_polygonal_surface3d.py b/src/opengeodeweb_back/geode_objects/geode_polygonal_surface3d.py new file mode 100644 index 00000000..4cba25e3 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_polygonal_surface3d.py @@ -0,0 +1,73 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_surface_mesh3d import GeodeSurfaceMesh3D + + +class GeodePolygonalSurface3D(GeodeSurfaceMesh3D): + polygonal_surface: og.PolygonalSurface3D + + def __init__(self, polygonal_surface: og.PolygonalSurface3D | None = None) -> None: + self.polygonal_surface = ( + polygonal_surface + if polygonal_surface is not None + else og.PolygonalSurface3D() + ) + super().__init__(self.polygonal_surface) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "PolygonalSurface3D" + + def native_extension(self) -> str: + return self.polygonal_surface.native_extension() + + def builder(self) -> og.PolygonalSurfaceBuilder3D: + return og.PolygonalSurfaceBuilder3D(self.polygonal_surface) + + @classmethod + def load_mesh(cls, filename: str) -> GeodePolygonalSurface3D: + return GeodePolygonalSurface3D(og.load_polygonal_surface3D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.polygonal_surface_additional_files3D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_polygonal_surface_loadable3D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.PolygonalSurfaceInputFactory3D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.PolygonalSurfaceOutputFactory3D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.polygonal_surface_object_priority3D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_polygonal_surface_saveable3D(self.polygonal_surface, filename) + + def save(self, filename: str) -> list[str]: + return og.save_polygonal_surface3D(self.polygonal_surface, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_polygonal_surface3D( + self.polygonal_surface, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_polygonal_surface3D( + self.polygonal_surface, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_polyhedral_solid3d.py b/src/opengeodeweb_back/geode_objects/geode_polyhedral_solid3d.py new file mode 100644 index 00000000..c76199c4 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_polyhedral_solid3d.py @@ -0,0 +1,71 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_solid_mesh3d import GeodeSolidMesh3D + + +class GeodePolyhedralSolid3D(GeodeSolidMesh3D): + polyhedral_solid: og.PolyhedralSolid3D + + def __init__(self, polyhedral_solid: og.PolyhedralSolid3D | None = None) -> None: + self.polyhedral_solid = ( + polyhedral_solid if polyhedral_solid is not None else og.PolyhedralSolid3D() + ) + super().__init__(self.polyhedral_solid) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "PolyhedralSolid3D" + + def native_extension(self) -> str: + return self.polyhedral_solid.native_extension() + + def builder(self) -> og.PolyhedralSolidBuilder3D: + return og.PolyhedralSolidBuilder3D(self.polyhedral_solid) + + @classmethod + def load_mesh(cls, filename: str) -> GeodePolyhedralSolid3D: + return GeodePolyhedralSolid3D(og.load_polyhedral_solid3D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.polyhedral_solid_additional_files3D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_polyhedral_solid_loadable3D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.PolyhedralSolidInputFactory3D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.PolyhedralSolidOutputFactory3D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.polyhedral_solid_object_priority3D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_polyhedral_solid_saveable3D(self.polyhedral_solid, filename) + + def save(self, filename: str) -> list[str]: + return og.save_polyhedral_solid3D(self.polyhedral_solid, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_polyhedral_solid3D( + self.polyhedral_solid, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_polyhedral_solid3D( + self.polyhedral_solid, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py b/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py index 4ab772a0..a8f75760 100644 --- a/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py @@ -27,7 +27,7 @@ def native_extension(self) -> str: @classmethod def is_3D(cls) -> bool: - return False + return True @classmethod def is_viewable(cls) -> bool: diff --git a/src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py b/src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py new file mode 100644 index 00000000..5bc8a3ce --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py @@ -0,0 +1,71 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_surface_mesh2d import GeodeSurfaceMesh2D + + +class GeodeRegularGrid2D(GeodeSurfaceMesh2D): + regular_grid: og.RegularGrid2D + + def __init__(self, regular_grid: og.RegularGrid2D | None = None) -> None: + self.regular_grid = ( + regular_grid if regular_grid is not None else og.RegularGrid2D() + ) + super().__init__(self.regular_grid) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "RegularGrid2D" + + def native_extension(self) -> str: + return self.regular_grid.native_extension() + + def builder(self) -> og.RegularGridBuilder2D: + return og.RegularGridBuilder2D(self.regular_grid) + + @classmethod + def load_mesh(cls, filename: str) -> GeodeRegularGrid2D: + return GeodeRegularGrid2D(og.load_regular_grid2D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.regular_grid_additional_files2D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_regular_grid_loadable2D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.RegularGridInputFactory2D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.RegularGridOutputFactory2D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.regular_grid_object_priority2D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_regular_grid_saveable2D(self.regular_grid, filename) + + def save(self, filename: str) -> list[str]: + return og.save_regular_grid2D(self.regular_grid, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_regular_grid2D( + self.regular_grid, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_regular_grid2D( + self.regular_grid, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_regulard_grid3d.py b/src/opengeodeweb_back/geode_objects/geode_regulard_grid3d.py new file mode 100644 index 00000000..628e6167 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_regulard_grid3d.py @@ -0,0 +1,71 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_solid_mesh3d import GeodeSolidMesh3D + + +class GeodeRegularGrid3D(GeodeSolidMesh3D): + regular_grid: og.RegularGrid3D + + def __init__(self, regular_grid: og.RegularGrid3D | None = None) -> None: + self.regular_grid = ( + regular_grid if regular_grid is not None else og.RegularGrid3D() + ) + super().__init__(self.regular_grid) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "RegularGrid3D" + + def native_extension(self) -> str: + return self.regular_grid.native_extension() + + def builder(self) -> og.RegularGridBuilder3D: + return og.RegularGridBuilder3D(self.regular_grid) + + @classmethod + def load_mesh(cls, filename: str) -> GeodeRegularGrid3D: + return GeodeRegularGrid3D(og.load_regular_grid3D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.regular_grid_additional_files3D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_regular_grid_loadable3D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.RegularGridInputFactory3D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.RegularGridOutputFactory3D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.regular_grid_object_priority3D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_regular_grid_saveable3D(self.regular_grid, filename) + + def save(self, filename: str) -> list[str]: + return og.save_regular_grid3D(self.regular_grid, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_regular_grid3D( + self.regular_grid, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_regular_grid3D( + self.regular_grid, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_section.py b/src/opengeodeweb_back/geode_objects/geode_section.py index b31643b7..75780ba3 100644 --- a/src/opengeodeweb_back/geode_objects/geode_section.py +++ b/src/opengeodeweb_back/geode_objects/geode_section.py @@ -3,6 +3,7 @@ # Third party imports import opengeode as og +import opengeode_geosciences as og_geosciences import opengeode_inspector as og_inspector import geode_viewables as viewables @@ -79,3 +80,27 @@ def mesh_components(self) -> ComponentRegistry: def inspect(self) -> og_inspector.SectionInspectionResult: return og_inspector.inspect_section(self.section) + + def assign_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.assign_section_geographic_coordinate_system_info( + self.section, builder, crs_name, info + ) + + def convert_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.convert_section_coordinate_reference_system( + self.section, builder, crs_name, info + ) + + def create_crs( + self, crs_name: str, input: og.CoordinateSystem2D, output: og.CoordinateSystem2D + ) -> None: + builder = self.builder() + og.create_section_coordinate_system( + self.section, builder, crs_name, input, output + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_solid_mesh3d.py b/src/opengeodeweb_back/geode_objects/geode_solid_mesh3d.py new file mode 100644 index 00000000..35be5e6d --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_solid_mesh3d.py @@ -0,0 +1,58 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_geosciences as og_geosciences +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_vertex_set import GeodeVertexSet + + +class GeodeSolidMesh3D(GeodeVertexSet): + solid_mesh: og.SolidMesh3D + + def __init__(self, solid_mesh: og.SolidMesh3D | None = None) -> None: + self.solid_mesh = solid_mesh if solid_mesh is not None else og.SolidMesh3D() + super().__init__(self.solid_mesh) + + @classmethod + def is_3D(cls) -> bool: + return True + + @classmethod + def is_viewable(cls) -> bool: + return True + + def builder(self) -> og.SolidMeshBuilder3D: + return og.SolidMeshBuilder3D.create(self.solid_mesh) + + def inspect(self) -> og_inspector.SolidInspectionResult: + return og_inspector.inspect_solid3D(self.solid_mesh) + + def assign_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.assign_solid_mesh_geographic_coordinate_system_info3D( + self.solid_mesh, builder, crs_name, info + ) + + def convert_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.convert_solid_mesh_coordinate_reference_system3D( + self.solid_mesh, builder, crs_name, info + ) + + def create_crs( + self, crs_name: str, input: og.CoordinateSystem2D, output: og.CoordinateSystem2D + ) -> None: + builder = self.builder() + og.create_solid_mesh_coordinate_system3D( + self.solid_mesh, builder, crs_name, input, output + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_surface_mesh2d.py b/src/opengeodeweb_back/geode_objects/geode_surface_mesh2d.py new file mode 100644 index 00000000..d86ee6ee --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_surface_mesh2d.py @@ -0,0 +1,60 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_geosciences as og_geosciences +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_vertex_set import GeodeVertexSet + + +class GeodeSurfaceMesh2D(GeodeVertexSet): + surface_mesh: og.SurfaceMesh2D + + def __init__(self, surface_mesh: og.SurfaceMesh2D | None = None) -> None: + self.surface_mesh = ( + surface_mesh if surface_mesh is not None else og.SurfaceMesh2D() + ) + super().__init__(self.surface_mesh) + + @classmethod + def is_3D(cls) -> bool: + return False + + @classmethod + def is_viewable(cls) -> bool: + return True + + def builder(self) -> og.SurfaceMeshBuilder2D: + return og.SurfaceMeshBuilder2D.create(self.surface_mesh) + + def inspect(self) -> og_inspector.SurfaceInspectionResult: + return og_inspector.inspect_surface2D(self.surface_mesh) + + def assign_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.assign_surface_mesh_geographic_coordinate_system_info2D( + self.surface_mesh, builder, crs_name, info + ) + + def convert_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.convert_surface_mesh_coordinate_reference_system2D( + self.surface_mesh, builder, crs_name, info + ) + + def create_crs( + self, crs_name: str, input: og.CoordinateSystem2D, output: og.CoordinateSystem2D + ) -> None: + builder = self.builder() + og.create_surface_mesh_coordinate_system2D( + self.surface_mesh, builder, crs_name, input, output + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_surface_mesh3d.py b/src/opengeodeweb_back/geode_objects/geode_surface_mesh3d.py new file mode 100644 index 00000000..a635ba15 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_surface_mesh3d.py @@ -0,0 +1,60 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_geosciences as og_geosciences +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_vertex_set import GeodeVertexSet + + +class GeodeSurfaceMesh3D(GeodeVertexSet): + surface_mesh: og.SurfaceMesh3D + + def __init__(self, surface_mesh: og.SurfaceMesh3D | None = None) -> None: + self.surface_mesh = ( + surface_mesh if surface_mesh is not None else og.SurfaceMesh3D() + ) + super().__init__(self.surface_mesh) + + @classmethod + def is_3D(cls) -> bool: + return True + + @classmethod + def is_viewable(cls) -> bool: + return True + + def builder(self) -> og.SurfaceMeshBuilder3D: + return og.SurfaceMeshBuilder3D.create(self.surface_mesh) + + def inspect(self) -> og_inspector.SurfaceInspectionResult: + return og_inspector.inspect_surface3D(self.surface_mesh) + + def assign_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.assign_surface_mesh_geographic_coordinate_system_info3D( + self.surface_mesh, builder, crs_name, info + ) + + def convert_crs( + self, crs_name: str, info: og_geosciences.GeographicCoordinateSystemInfo + ) -> None: + builder = self.builder() + og_geosciences.convert_surface_mesh_coordinate_reference_system3D( + self.surface_mesh, builder, crs_name, info + ) + + def create_crs( + self, crs_name: str, input: og.CoordinateSystem2D, output: og.CoordinateSystem2D + ) -> None: + builder = self.builder() + og.create_surface_mesh_coordinate_system3D( + self.surface_mesh, builder, crs_name, input, output + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_tetrahedral_solid3d.py b/src/opengeodeweb_back/geode_objects/geode_tetrahedral_solid3d.py new file mode 100644 index 00000000..15dc10c2 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_tetrahedral_solid3d.py @@ -0,0 +1,73 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_solid_mesh3d import GeodeSolidMesh3D + + +class GeodeTetrahedralSolid3D(GeodeSolidMesh3D): + tetrahedral_solid: og.TetrahedralSolid3D + + def __init__(self, tetrahedral_solid: og.TetrahedralSolid3D | None = None) -> None: + self.tetrahedral_solid = ( + tetrahedral_solid + if tetrahedral_solid is not None + else og.TetrahedralSolid3D() + ) + super().__init__(self.tetrahedral_solid) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "TetrahedralSolid3D" + + def native_extension(self) -> str: + return self.tetrahedral_solid.native_extension() + + def builder(self) -> og.TetrahedralSolidBuilder3D: + return og.TetrahedralSolidBuilder3D(self.tetrahedral_solid) + + @classmethod + def load_mesh(cls, filename: str) -> GeodeTetrahedralSolid3D: + return GeodeTetrahedralSolid3D(og.load_tetrahedral_solid3D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.tetrahedral_solid_additional_files3D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_tetrahedral_solid_loadable3D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.TetrahedralSolidInputFactory3D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.TetrahedralSolidOutputFactory3D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.tetrahedral_solid_object_priority3D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_tetrahedral_solid_saveable3D(self.tetrahedral_solid, filename) + + def save(self, filename: str) -> list[str]: + return og.save_tetrahedral_solid3D(self.tetrahedral_solid, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_tetrahedral_solid3D( + self.tetrahedral_solid, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_tetrahedral_solid3D( + self.tetrahedral_solid, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_triangulated_surface2d.py b/src/opengeodeweb_back/geode_objects/geode_triangulated_surface2d.py new file mode 100644 index 00000000..9e0558ee --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_triangulated_surface2d.py @@ -0,0 +1,77 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_surface_mesh2d import GeodeSurfaceMesh2D + + +class GeodeTriangulatedSurface2D(GeodeSurfaceMesh2D): + triangulated_surface: og.TriangulatedSurface2D + + def __init__( + self, triangulated_surface: og.TriangulatedSurface2D | None = None + ) -> None: + self.triangulated_surface = ( + triangulated_surface + if triangulated_surface is not None + else og.TriangulatedSurface2D() + ) + super().__init__(self.triangulated_surface) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "TriangulatedSurface2D" + + def native_extension(self) -> str: + return self.triangulated_surface.native_extension() + + def builder(self) -> og.TriangulatedSurfaceBuilder2D: + return og.TriangulatedSurfaceBuilder2D(self.triangulated_surface) + + @classmethod + def load_mesh(cls, filename: str) -> GeodeTriangulatedSurface2D: + return GeodeTriangulatedSurface2D(og.load_triangulated_surface2D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.triangulated_surface_additional_files2D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_triangulated_surface_loadable2D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.TriangulatedSurfaceInputFactory2D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.TriangulatedSurfaceOutputFactory2D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.triangulated_surface_object_priority2D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_triangulated_surface_saveable2D( + self.triangulated_surface, filename + ) + + def save(self, filename: str) -> list[str]: + return og.save_triangulated_surface2D(self.triangulated_surface, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_triangulated_surface2D( + self.triangulated_surface, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_triangulated_surface2D( + self.triangulated_surface, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/geode_triangulated_surface3d.py b/src/opengeodeweb_back/geode_objects/geode_triangulated_surface3d.py new file mode 100644 index 00000000..d5b3e81c --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_triangulated_surface3d.py @@ -0,0 +1,77 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_inspector as og_inspector +import geode_viewables as viewables + +# Local application imports +from .types import GeodeMeshType +from .geode_surface_mesh3d import GeodeSurfaceMesh3D + + +class GeodeTriangulatedSurface3D(GeodeSurfaceMesh3D): + triangulated_surface: og.TriangulatedSurface3D + + def __init__( + self, triangulated_surface: og.TriangulatedSurface3D | None = None + ) -> None: + self.triangulated_surface = ( + triangulated_surface + if triangulated_surface is not None + else og.TriangulatedSurface3D() + ) + super().__init__(self.triangulated_surface) + + @classmethod + def geode_mesh_type(cls) -> GeodeMeshType: + return "TriangulatedSurface3D" + + def native_extension(self) -> str: + return self.triangulated_surface.native_extension() + + def builder(self) -> og.TriangulatedSurfaceBuilder3D: + return og.TriangulatedSurfaceBuilder3D(self.triangulated_surface) + + @classmethod + def load_mesh(cls, filename: str) -> GeodeTriangulatedSurface3D: + return GeodeTriangulatedSurface3D(og.load_triangulated_surface3D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + return og.triangulated_surface_additional_files3D(filename) + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + return og.is_triangulated_surface_loadable3D(filename) + + @classmethod + def input_extensions(cls) -> list[str]: + return og.TriangulatedSurfaceInputFactory3D.list_creators() + + @classmethod + def output_extensions(cls) -> list[str]: + return og.TriangulatedSurfaceOutputFactory3D.list_creators() + + @classmethod + def object_priority(cls, filename: str) -> int: + return og.triangulated_surface_object_priority3D(filename) + + def is_saveable(self, filename: str) -> bool: + return og.is_triangulated_surface_saveable3D( + self.triangulated_surface, filename + ) + + def save(self, filename: str) -> list[str]: + return og.save_triangulated_surface3D(self.triangulated_surface, filename) + + def save_viewable(self, filename_without_extension: str) -> str: + return viewables.save_viewable_triangulated_surface3D( + self.triangulated_surface, filename_without_extension + ) + + def save_light_viewable(self, filename_without_extension: str) -> str: + return viewables.save_light_viewable_triangulated_surface3D( + self.triangulated_surface, filename_without_extension + ) diff --git a/src/opengeodeweb_back/geode_objects/types.py b/src/opengeodeweb_back/geode_objects/types.py index a032f63b..943f3856 100644 --- a/src/opengeodeweb_back/geode_objects/types.py +++ b/src/opengeodeweb_back/geode_objects/types.py @@ -6,19 +6,37 @@ # Local application imports -GeodeSurfaceMeshType = Literal["PolygonalSurface3D"] +GeodeSurfaceMeshType = Literal[ + "PolygonalSurface2D", + "PolygonalSurface3D", + "TriangulatedSurface2D", + "TriangulatedSurface3D", + "RegularGrid2D", +] +GeodeSolidMeshType = Literal[ + "PolyhedralSolid3D", + "TetrahedralSolid3D", + "HybridSolid3D", + "RegularGrid3D", +] +GeodeGridType = Literal[ + "LightRegularGrid2D", + "LightRegularGrid3D", +] GeodeMeshType = ( Literal[ "VertexSet", "Graph", "PointSet2D", "PointSet3D", - "EdgeCurve2D", - "EdgeCurve3D", + "EdgedCurve2D", + "EdgedCurve3D", "RasterImage2D", "RasterImage3D", ] | GeodeSurfaceMeshType + | GeodeSolidMeshType + | GeodeGridType ) GeodeModelType = Literal[ "BRep", @@ -42,6 +60,8 @@ def _flatten_literal_args(literal: object) -> tuple[str, ...]: GeodeSurfaceMeshType_values = _flatten_literal_args(GeodeSurfaceMeshType) +GeodeSolidMeshType_values = _flatten_literal_args(GeodeSolidMeshType) +GeodeGridType_values = _flatten_literal_args(GeodeGridType) GeodeMeshType_values = _flatten_literal_args(GeodeMeshType) GeodeModelType_values = _flatten_literal_args(GeodeModelType) GeodeObjectType_values = _flatten_literal_args(GeodeObjectType) @@ -63,6 +83,22 @@ def geode_mesh_type(value: str) -> GeodeMeshType: return cast(GeodeMeshType, value) +def geode_surface_mesh_type(value: str) -> GeodeSurfaceMeshType: + if value not in GeodeSurfaceMeshType_values: + raise ValueError( + f"Invalid GeodeSurfaceMeshType: {value!r}. Must be one of {GeodeSurfaceMeshType_values}" + ) + return cast(GeodeSurfaceMeshType, value) + + +def geode_solid_mesh_type(value: str) -> GeodeSolidMeshType: + if value not in GeodeSolidMeshType_values: + raise ValueError( + f"Invalid GeodeSolidMeshType: {value!r}. Must be one of {GeodeSolidMeshType_values}" + ) + return cast(GeodeSolidMeshType, value) + + def geode_model_type(value: str) -> GeodeModelType: if value not in GeodeModelType_values: raise ValueError( diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index 901e46b0..6a88c31d 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -4,7 +4,7 @@ import time import zipfile from collections.abc import Callable -from concurrent.futures import ThreadPoolExecutor +from concurrent.futures import ThreadPoolExecutor, Future # Third party imports import flask @@ -184,25 +184,30 @@ def save_all_viewables_and_return_info( data_path: str, ) -> dict[str, str | list[str]]: with ThreadPoolExecutor() as executor: - native_future = executor.submit( - geode_object.save, - os.path.join(data_path, "native." + geode_object.native_extension()), + (native_files, viewable_path, light_path) = executor.map( + lambda func_path: func_path[0](), + [ + ( + geode_object.save, + os.path.join( + data_path, "native." + geode_object.native_extension() + ), + ), + (geode_object.save_viewable, os.path.join(data_path, "viewable")), + ( + geode_object.save_light_viewable, + os.path.join(data_path, "light_viewable"), + ), + ], ) - viewable_future = executor.submit( - geode_object.save_viewable, os.path.join(data_path, "viewable") - ) - light_viewable_future = executor.submit( - geode_object.save_light_viewable, os.path.join(data_path, "light_viewable") - ) - saved_light_viewable_file_path = light_viewable_future.result() - with open(saved_light_viewable_file_path, "rb") as f: + with open(light_path, "rb") as f: binary_light_viewable = f.read() - saved_native_file_path = native_future.result() - saved_viewable_file_path = viewable_future.result() - data.native_file_name = os.path.basename(saved_native_file_path[0]) - data.viewable_file_name = os.path.basename(saved_viewable_file_path) - data.light_viewable = os.path.basename(saved_light_viewable_file_path) - + data.native_file_name = os.path.basename(native_files[0]) + data.viewable_file_name = os.path.basename(viewable_path) + data.light_viewable = os.path.basename(light_path) + assert data.native_file_name is not None + assert data.viewable_file_name is not None + assert data.light_viewable is not None return { "native_file_name": data.native_file_name, "viewable_file_name": data.viewable_file_name, From 837a3e19ee1fabb845f0cf55a39871fc9afda84e Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Mon, 24 Nov 2025 11:13:34 +0100 Subject: [PATCH 07/21] feat(GeodeObject): new design using OpenGeode types --- requirements.in | 2 +- requirements.txt | 2 +- src/opengeodeweb_back/geode_functions.py | 40 +- .../geode_objects/__init__.py | 9 +- .../geode_objects/geode_brep.py | 4 +- .../geode_objects/geode_cross_section.py | 4 +- .../geode_objects/geode_edged_curve2d.py | 10 +- .../geode_objects/geode_edged_curve3d.py | 10 +- .../geode_objects/geode_graph.py | 8 +- .../geode_objects/geode_hybrid_solid3d.py | 8 +- .../geode_implicit_cross_section.py | 4 +- .../geode_implicit_structural_model.py | 4 +- .../geode_light_regular_grid2d.py | 7 +- .../geode_light_regular_grid3d.py | 7 +- .../geode_objects/geode_mesh.py | 24 +- .../geode_objects/geode_model.py | 16 - .../geode_objects/geode_object.py | 560 ------------------ .../geode_objects/geode_point_set2d.py | 8 +- .../geode_objects/geode_point_set3d.py | 8 +- .../geode_polygonal_surface2d.py | 8 +- .../geode_polygonal_surface3d.py | 8 +- .../geode_objects/geode_polyhedral_solid3d.py | 10 +- .../geode_objects/geode_raster_image2d.py | 4 +- .../geode_objects/geode_raster_image3d.py | 4 +- .../geode_objects/geode_regulard_grid2d.py | 8 +- .../geode_objects/geode_regulard_grid3d.py | 8 +- .../geode_objects/geode_section.py | 4 +- .../geode_objects/geode_solid_mesh3d.py | 3 + .../geode_objects/geode_structural_model.py | 4 +- .../geode_objects/geode_surface_mesh2d.py | 8 +- .../geode_objects/geode_surface_mesh3d.py | 8 +- .../geode_tetrahedral_solid3d.py | 8 +- .../geode_triangulated_surface2d.py | 8 +- .../geode_triangulated_surface3d.py | 8 +- .../geode_objects/geode_vertex_set.py | 13 +- src/opengeodeweb_back/geode_objects/types.py | 66 +-- .../routes/blueprint_routes.py | 36 +- .../routes/create/blueprint_create.py | 36 +- .../routes/models/blueprint_models.py | 5 +- src/opengeodeweb_back/test_utils.py | 4 +- src/opengeodeweb_back/utils_functions.py | 3 +- tests/test_create_routes.py | 55 +- tests/test_models_routes.py | 8 +- tests/test_routes.py | 31 +- 44 files changed, 230 insertions(+), 863 deletions(-) diff --git a/requirements.in b/requirements.in index 68044040..1f319112 100644 --- a/requirements.in +++ b/requirements.in @@ -1,4 +1,4 @@ -opengeode-core==15.30.3 +opengeode-core==15.30.4 opengeode-io==7.4.6 opengeode-inspector==6.8.6 opengeode-geosciences==9.5.5 diff --git a/requirements.txt b/requirements.txt index d293d980..08d64bdf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,7 +31,7 @@ markupsafe>=3 # flask # jinja2 # werkzeug -opengeode-core==15.30.3 +opengeode-core==15.30.4 # via # -r requirements.in # geode-common diff --git a/src/opengeodeweb_back/geode_functions.py b/src/opengeodeweb_back/geode_functions.py index e3ffed58..1a4e4590 100644 --- a/src/opengeodeweb_back/geode_functions.py +++ b/src/opengeodeweb_back/geode_functions.py @@ -9,18 +9,12 @@ from typing import Any # Local application imports -from .geode_objects import geode_objects, geode_meshes, geode_models +from .geode_objects import geode_objects from .geode_objects.types import ( GeodeObjectType, geode_object_type, - GeodeMeshType, - geode_mesh_type, - GeodeModelType, - geode_model_type, ) from .geode_objects.geode_object import GeodeObject -from .geode_objects.geode_mesh import GeodeMesh -from .geode_objects.geode_model import GeodeModel from . import utils_functions from opengeodeweb_microservice.database.data import Data from opengeodeweb_microservice.database.connection import get_session @@ -38,15 +32,7 @@ def geode_object_from_string(value: str) -> type[GeodeObject]: return geode_objects[geode_object_type(value)] -def geode_mesh_from_string(value: str) -> type[GeodeMesh]: - return geode_meshes[geode_mesh_type(value)] - - -def geode_model_from_string(value: str) -> type[GeodeModel]: - return geode_models[geode_model_type(value)] - - -def load_object_data(data_id: str) -> GeodeObject: +def load_geode_object(data_id: str) -> GeodeObject: data = Data.get(data_id) if not data: flask.abort(404, f"Data with id {data_id} not found") @@ -57,28 +43,6 @@ def load_object_data(data_id: str) -> GeodeObject: return geode_object_from_string(data.geode_object).load(file_absolute_path) -def load_mesh_data(data_id: str) -> GeodeMesh: - data = Data.get(data_id) - if not data: - flask.abort(404, f"Data with id {data_id} not found") - - file_absolute_path = data_file_path(data_id, data.native_file_name) - print("Loading file: ", file_absolute_path) - print("File exists: ", os.path.exists(file_absolute_path)) - return geode_mesh_from_string(data.geode_object).load_mesh(file_absolute_path) - - -def load_model_data(data_id: str) -> GeodeModel: - data = Data.get(data_id) - if not data: - flask.abort(404, f"Data with id {data_id} not found") - - file_absolute_path = data_file_path(data_id, data.native_file_name) - print("Loading file: ", file_absolute_path) - print("File exists: ", os.path.exists(file_absolute_path)) - return geode_model_from_string(data.geode_object).load_model(file_absolute_path) - - def get_data_info(data_id: str) -> Data: data = Data.get(data_id) if not data: diff --git a/src/opengeodeweb_back/geode_objects/__init__.py b/src/opengeodeweb_back/geode_objects/__init__.py index fa7cc64e..6d41d4d6 100644 --- a/src/opengeodeweb_back/geode_objects/__init__.py +++ b/src/opengeodeweb_back/geode_objects/__init__.py @@ -42,7 +42,7 @@ from .geode_implicit_structural_model import GeodeImplicitStructuralModel from .geode_implicit_cross_section import GeodeImplicitCrossSection -geode_meshes: dict[GeodeMeshType, type[GeodeMesh]] = { +geode_objects: dict[GeodeObjectType, type[GeodeObject]] = { "VertexSet": GeodeVertexSet, "Graph": GeodeGraph, "PointSet2D": GeodePointSet2D, @@ -62,8 +62,6 @@ "RegularGrid3D": GeodeRegularGrid3D, "LightRegularGrid2D": GeodeLightRegularGrid2D, "LightRegularGrid3D": GeodeLightRegularGrid3D, -} -geode_models: dict[GeodeModelType, type[GeodeModel]] = { "BRep": GeodeBRep, "Section": GeodeSection, "StructuralModel": GeodeStructuralModel, @@ -71,8 +69,3 @@ "ImplicitStructuralModel": GeodeImplicitStructuralModel, "ImplicitCrossSection": GeodeImplicitCrossSection, } - -GeodeObjectsDict = dict[GeodeObjectType, type[GeodeObject]] -geode_objects: GeodeObjectsDict = {} -geode_objects.update(cast(GeodeObjectsDict, geode_meshes)) -geode_objects.update(cast(GeodeObjectsDict, geode_models)) diff --git a/src/opengeodeweb_back/geode_objects/geode_brep.py b/src/opengeodeweb_back/geode_objects/geode_brep.py index a86bbf3f..6637fb9a 100644 --- a/src/opengeodeweb_back/geode_objects/geode_brep.py +++ b/src/opengeodeweb_back/geode_objects/geode_brep.py @@ -20,7 +20,7 @@ def __init__(self, brep: og.BRep | None = None) -> None: super().__init__(self.brep) @classmethod - def geode_model_type(cls) -> GeodeModelType: + def geode_object_type(cls) -> GeodeModelType: return "BRep" def native_extension(self) -> str: @@ -38,7 +38,7 @@ def builder(self) -> og.BRepBuilder: return og.BRepBuilder(self.brep) @classmethod - def load_model(cls, filename: str) -> GeodeBRep: + def load(cls, filename: str) -> GeodeBRep: return GeodeBRep(og.load_brep(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_cross_section.py b/src/opengeodeweb_back/geode_objects/geode_cross_section.py index 8d81a28b..bfeda2c6 100644 --- a/src/opengeodeweb_back/geode_objects/geode_cross_section.py +++ b/src/opengeodeweb_back/geode_objects/geode_cross_section.py @@ -25,7 +25,7 @@ def __init__( super().__init__(self.cross_section) @classmethod - def geode_model_type(cls) -> GeodeModelType: + def geode_object_type(cls) -> GeodeModelType: return "CrossSection" def native_extension(self) -> str: @@ -35,7 +35,7 @@ def builder(self) -> og_geosciences.CrossSectionBuilder: return og_geosciences.CrossSectionBuilder(self.cross_section) @classmethod - def load_model(cls, filename: str) -> GeodeCrossSection: + def load(cls, filename: str) -> GeodeCrossSection: return GeodeCrossSection(og_geosciences.load_cross_section(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py b/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py index 143d2df3..bcb4e8d8 100644 --- a/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py @@ -16,11 +16,13 @@ class GeodeEdgedCurve2D(GeodeGraph): edged_curve: og.EdgedCurve2D def __init__(self, edged_curve: og.EdgedCurve2D | None = None) -> None: - self.edged_curve = edged_curve if edged_curve is not None else og.EdgedCurve2D() + self.edged_curve = ( + edged_curve if edged_curve is not None else og.EdgedCurve2D.create() + ) super().__init__(self.edged_curve) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "EdgedCurve2D" def native_extension(self) -> str: @@ -35,10 +37,10 @@ def is_viewable(cls) -> bool: return False def builder(self) -> og.EdgedCurveBuilder2D: - return og.EdgedCurveBuilder2D(self.edged_curve) + return og.EdgedCurveBuilder2D.create(self.edged_curve) @classmethod - def load_mesh(cls, filename: str) -> GeodeEdgedCurve2D: + def load(cls, filename: str) -> GeodeEdgedCurve2D: return GeodeEdgedCurve2D(og.load_edged_curve2D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py b/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py index 017608ab..0f35a212 100644 --- a/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py @@ -16,11 +16,13 @@ class GeodeEdgedCurve3D(GeodeGraph): edged_curve: og.EdgedCurve3D def __init__(self, edged_curve: og.EdgedCurve3D | None = None) -> None: - self.edged_curve = edged_curve if edged_curve is not None else og.EdgedCurve3D() + self.edged_curve = ( + edged_curve if edged_curve is not None else og.EdgedCurve3D.create() + ) super().__init__(self.edged_curve) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "EdgedCurve3D" def native_extension(self) -> str: @@ -35,10 +37,10 @@ def is_viewable(cls) -> bool: return False def builder(self) -> og.EdgedCurveBuilder3D: - return og.EdgedCurveBuilder3D(self.edged_curve) + return og.EdgedCurveBuilder3D.create(self.edged_curve) @classmethod - def load_mesh(cls, filename: str) -> GeodeEdgedCurve3D: + def load(cls, filename: str) -> GeodeEdgedCurve3D: return GeodeEdgedCurve3D(og.load_edged_curve3D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_graph.py b/src/opengeodeweb_back/geode_objects/geode_graph.py index dc90b1a1..cd12775c 100644 --- a/src/opengeodeweb_back/geode_objects/geode_graph.py +++ b/src/opengeodeweb_back/geode_objects/geode_graph.py @@ -15,11 +15,11 @@ class GeodeGraph(GeodeVertexSet): graph: og.Graph def __init__(self, graph: og.Graph | None = None) -> None: - self.graph = graph if graph is not None else og.Graph() + self.graph = graph if graph is not None else og.Graph.create() super().__init__(self.graph) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "Graph" def native_extension(self) -> str: @@ -34,10 +34,10 @@ def is_viewable(cls) -> bool: return False def builder(self) -> og.GraphBuilder: - return og.GraphBuilder(self.graph) + return og.GraphBuilder.create(self.graph) @classmethod - def load_mesh(cls, filename: str) -> GeodeGraph: + def load(cls, filename: str) -> GeodeGraph: return GeodeGraph(og.load_graph(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_hybrid_solid3d.py b/src/opengeodeweb_back/geode_objects/geode_hybrid_solid3d.py index 5cef1e34..8a22d9be 100644 --- a/src/opengeodeweb_back/geode_objects/geode_hybrid_solid3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_hybrid_solid3d.py @@ -16,22 +16,22 @@ class GeodeHybridSolid3D(GeodeSolidMesh3D): def __init__(self, hybrid_solid: og.HybridSolid3D | None = None) -> None: self.hybrid_solid = ( - hybrid_solid if hybrid_solid is not None else og.HybridSolid3D() + hybrid_solid if hybrid_solid is not None else og.HybridSolid3D.create() ) super().__init__(self.hybrid_solid) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "HybridSolid3D" def native_extension(self) -> str: return self.hybrid_solid.native_extension() def builder(self) -> og.HybridSolidBuilder3D: - return og.HybridSolidBuilder3D(self.hybrid_solid) + return og.HybridSolidBuilder3D.create(self.hybrid_solid) @classmethod - def load_mesh(cls, filename: str) -> GeodeHybridSolid3D: + def load(cls, filename: str) -> GeodeHybridSolid3D: return GeodeHybridSolid3D(og.load_hybrid_solid3D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_implicit_cross_section.py b/src/opengeodeweb_back/geode_objects/geode_implicit_cross_section.py index 05c9d8a7..8f9a4e41 100644 --- a/src/opengeodeweb_back/geode_objects/geode_implicit_cross_section.py +++ b/src/opengeodeweb_back/geode_objects/geode_implicit_cross_section.py @@ -25,7 +25,7 @@ def __init__( super().__init__(self.implicit_cross_section) @classmethod - def geode_model_type(cls) -> GeodeModelType: + def geode_object_type(cls) -> GeodeModelType: return "ImplicitCrossSection" def native_extension(self) -> str: @@ -35,7 +35,7 @@ def builder(self) -> og_geosciences.ImplicitCrossSectionBuilder: return og_geosciences.ImplicitCrossSectionBuilder(self.implicit_cross_section) @classmethod - def load_model(cls, filename: str) -> GeodeImplicitCrossSection: + def load(cls, filename: str) -> GeodeImplicitCrossSection: return GeodeImplicitCrossSection( og_geosciences.load_implicit_cross_section(filename) ) diff --git a/src/opengeodeweb_back/geode_objects/geode_implicit_structural_model.py b/src/opengeodeweb_back/geode_objects/geode_implicit_structural_model.py index 1adcdb02..0df5a5b6 100644 --- a/src/opengeodeweb_back/geode_objects/geode_implicit_structural_model.py +++ b/src/opengeodeweb_back/geode_objects/geode_implicit_structural_model.py @@ -27,7 +27,7 @@ def __init__( super().__init__(self.implicit_structural_model) @classmethod - def geode_model_type(cls) -> GeodeModelType: + def geode_object_type(cls) -> GeodeModelType: return "ImplicitStructuralModel" def native_extension(self) -> str: @@ -39,7 +39,7 @@ def builder(self) -> og_geosciences.ImplicitStructuralModelBuilder: ) @classmethod - def load_model(cls, filename: str) -> GeodeImplicitStructuralModel: + def load(cls, filename: str) -> GeodeImplicitStructuralModel: return GeodeImplicitStructuralModel( og_geosciences.load_implicit_structural_model(filename) ) diff --git a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py index 071c8631..9ab855d1 100644 --- a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py @@ -19,14 +19,14 @@ def __init__(self, light_regular_grid: og.LightRegularGrid2D) -> None: super().__init__(self.light_regular_grid) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "LightRegularGrid2D" def native_extension(self) -> str: return self.light_regular_grid.native_extension() @classmethod - def load_mesh(cls, filename: str) -> GeodeLightRegularGrid2D: + def load(cls, filename: str) -> GeodeLightRegularGrid2D: return GeodeLightRegularGrid2D(og.load_light_regular_grid2D(filename)) @classmethod @@ -64,3 +64,6 @@ def save_light_viewable(self, filename_without_extension: str) -> str: return viewables.save_light_viewable_light_regular_grid2D( self.light_regular_grid, filename_without_extension ) + + def vertex_attribute_manager(self) -> og.AttributeManager: + return self.light_regular_grid.grid_vertex_attribute_manager() diff --git a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py index dfb43f1c..0f6b52b9 100644 --- a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py @@ -19,14 +19,14 @@ def __init__(self, light_regular_grid: og.LightRegularGrid3D) -> None: super().__init__(self.light_regular_grid) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "LightRegularGrid3D" def native_extension(self) -> str: return self.light_regular_grid.native_extension() @classmethod - def load_mesh(cls, filename: str) -> GeodeLightRegularGrid3D: + def load(cls, filename: str) -> GeodeLightRegularGrid3D: return GeodeLightRegularGrid3D(og.load_light_regular_grid3D(filename)) @classmethod @@ -64,3 +64,6 @@ def save_light_viewable(self, filename_without_extension: str) -> str: return viewables.save_light_viewable_light_regular_grid3D( self.light_regular_grid, filename_without_extension ) + + def vertex_attribute_manager(self) -> og.AttributeManager: + return self.light_regular_grid.grid_vertex_attribute_manager() diff --git a/src/opengeodeweb_back/geode_objects/geode_mesh.py b/src/opengeodeweb_back/geode_objects/geode_mesh.py index b7162e34..6680eca4 100644 --- a/src/opengeodeweb_back/geode_objects/geode_mesh.py +++ b/src/opengeodeweb_back/geode_objects/geode_mesh.py @@ -1,33 +1,19 @@ # Standard library imports from __future__ import annotations -from abc import ABC, abstractmethod -from typing import Literal, Any, get_args, cast +from abc import abstractmethod # Third party imports import opengeode as og # Local application imports -from .types import GeodeObjectType, GeodeMeshType, ViewerType +from .types import GeodeObjectType, ViewerType from .geode_object import GeodeObject class GeodeMesh(GeodeObject): - @classmethod - def load(cls, filename: str) -> GeodeObject: - return cls.load_mesh(filename) - - @classmethod - @abstractmethod - def load_mesh(cls, filename: str) -> GeodeMesh: ... - - @classmethod - def geode_object_type(cls) -> GeodeObjectType: - return cls.geode_mesh_type() - - @classmethod - @abstractmethod - def geode_mesh_type(cls) -> GeodeMeshType: ... - @classmethod def viewer_type(cls) -> ViewerType: return "mesh" + + @abstractmethod + def vertex_attribute_manager(self) -> og.AttributeManager: ... diff --git a/src/opengeodeweb_back/geode_objects/geode_model.py b/src/opengeodeweb_back/geode_objects/geode_model.py index 399bd6b9..8715c8f3 100644 --- a/src/opengeodeweb_back/geode_objects/geode_model.py +++ b/src/opengeodeweb_back/geode_objects/geode_model.py @@ -14,22 +14,6 @@ class GeodeModel(GeodeObject): - @classmethod - def load(cls, filename: str) -> GeodeObject: - return cls.load_model(filename) - - @classmethod - @abstractmethod - def load_model(cls, filename: str) -> GeodeModel: ... - - @classmethod - def geode_object_type(cls) -> GeodeObjectType: - return cls.geode_model_type() - - @classmethod - @abstractmethod - def geode_model_type(cls) -> GeodeModelType: ... - @classmethod def viewer_type(cls) -> ViewerType: return "model" diff --git a/src/opengeodeweb_back/geode_objects/geode_object.py b/src/opengeodeweb_back/geode_objects/geode_object.py index 1bb0f85e..8c44ef45 100644 --- a/src/opengeodeweb_back/geode_objects/geode_object.py +++ b/src/opengeodeweb_back/geode_objects/geode_object.py @@ -76,563 +76,3 @@ def save_light_viewable(self, filename_without_extension: str) -> str: ... @abstractmethod def inspect(self) -> Any: ... - - -mesh = "mesh" -model = "model" - -points = "points" -edges = "edges" -polygons = "polygons" -polyhedrons = "polyhedrons" - - -# def geode_objects_dict(): -# return { -# "BRep": { -# "class": og.BRep, -# "input_factory": og.BRepInputFactory, -# "output_factory": og.BRepOutputFactory, -# "additional_files": og.brep_additional_files, -# "is_loadable": og.is_brep_loadable, -# "object_priority": og.brep_object_priority, -# "load": og.load_brep, -# "is_saveable": og.is_brep_saveable, -# "save": og.save_brep, -# "builder": og.BRepBuilder, -# "crs": { -# "assign": og_gs.assign_brep_geographic_coordinate_system_info, -# "convert": og_gs.convert_brep_coordinate_reference_system, -# "create": og.create_brep_coordinate_system, -# }, -# "object_type": model, -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_brep, -# "save_light_viewable": g_v.save_light_viewable_brep, -# "inspector": og_inspector.inspect_brep, -# }, -# "CrossSection": { -# "parent": "Section", -# "class": og_gs.CrossSection, -# "input_factory": og_gs.CrossSectionInputFactory, -# "output_factory": og_gs.CrossSectionOutputFactory, -# "additional_files": og_gs.cross_section_additional_files, -# "is_loadable": og_gs.is_cross_section_loadable, -# "object_priority": og_gs.cross_section_object_priority, -# "load": og_gs.load_cross_section, -# "is_saveable": og_gs.is_cross_section_saveable, -# "save": og_gs.save_cross_section, -# "builder": og_gs.CrossSectionBuilder, -# "crs": { -# "assign": og_gs.assign_section_geographic_coordinate_system_info, -# "convert": og_gs.convert_section_coordinate_reference_system, -# "create": og.create_section_coordinate_system, -# }, -# "object_type": model, -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_cross_section, -# "save_light_viewable": g_v.save_light_viewable_cross_section, -# "inspector": og_inspector.inspect_section, -# }, -# "EdgedCurve2D": { -# "class": og.EdgedCurve2D, -# "input_factory": og.EdgedCurveInputFactory2D, -# "output_factory": og.EdgedCurveOutputFactory2D, -# "additional_files": og.edged_curve_additional_files2D, -# "is_loadable": og.is_edged_curve_loadable2D, -# "object_priority": og.edged_curve_object_priority2D, -# "load": og.load_edged_curve2D, -# "is_saveable": og.is_edged_curve_saveable2D, -# "save": og.save_edged_curve2D, -# "builder": og.EdgedCurveBuilder2D.create, -# "crs": { -# "assign": og_gs.assign_edged_curve_geographic_coordinate_system_info2D, -# "convert": og_gs.convert_edged_curve_coordinate_reference_system2D, -# "create": og.create_edged_curve_coordinate_system2D, -# }, -# "object_type": mesh, -# "elements": [points, edges], -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_edged_curve2D, -# "save_light_viewable": g_v.save_light_viewable_edged_curve2D, -# "inspector": og_inspector.inspect_edged_curve2D, -# }, -# "EdgedCurve3D": { -# "class": og.EdgedCurve3D, -# "input_factory": og.EdgedCurveInputFactory3D, -# "output_factory": og.EdgedCurveOutputFactory3D, -# "additional_files": og.edged_curve_additional_files3D, -# "is_loadable": og.is_edged_curve_loadable3D, -# "object_priority": og.edged_curve_object_priority3D, -# "load": og.load_edged_curve3D, -# "is_saveable": og.is_edged_curve_saveable3D, -# "save": og.save_edged_curve3D, -# "builder": og.EdgedCurveBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_edged_curve_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_edged_curve_coordinate_reference_system3D, -# "create": og.create_edged_curve_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points, edges], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_edged_curve3D, -# "save_light_viewable": g_v.save_light_viewable_edged_curve3D, -# "inspector": og_inspector.inspect_edged_curve3D, -# }, -# "Graph": { -# "class": og.Graph, -# "input_factory": og.GraphInputFactory, -# "output_factory": og.GraphOutputFactory, -# "additional_files": og.graph_additional_files, -# "is_loadable": og.is_graph_loadable, -# "object_priority": og.graph_object_priority, -# "load": og.load_graph, -# "is_saveable": og.is_graph_saveable, -# "save": og.save_graph, -# "builder": og.GraphBuilder.create, -# "object_type": mesh, -# "is_3D": False, -# "is_viewable": False, -# }, -# "HybridSolid3D": { -# "class": og.HybridSolid3D, -# "input_factory": og.HybridSolidInputFactory3D, -# "output_factory": og.HybridSolidOutputFactory3D, -# "additional_files": og.hybrid_solid_additional_files3D, -# "is_loadable": og.is_hybrid_solid_loadable3D, -# "object_priority": og.hybrid_solid_object_priority3D, -# "load": og.load_hybrid_solid3D, -# "is_saveable": og.is_hybrid_solid_saveable3D, -# "save": og.save_hybrid_solid3D, -# "builder": og.HybridSolidBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, -# "create": og.create_solid_mesh_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points, polyhedrons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_hybrid_solid3D, -# "save_light_viewable": g_v.save_light_viewable_hybrid_solid3D, -# "inspector": og_inspector.inspect_solid3D, -# }, -# "ImplicitCrossSection": { -# "parent": "CrossSection", -# "class": og_gs.ImplicitCrossSection, -# "input_factory": og_gs.ImplicitCrossSectionInputFactory, -# "output_factory": og_gs.ImplicitCrossSectionOutputFactory, -# "additional_files": og_gs.implicit_cross_section_additional_files, -# "is_loadable": og_gs.is_implicit_cross_section_loadable, -# "object_priority": og_gs.implicit_cross_section_object_priority, -# "load": og_gs.load_implicit_cross_section, -# "is_saveable": og_gs.is_implicit_cross_section_saveable, -# "save": og_gs.save_implicit_cross_section, -# "builder": og_gs.ImplicitCrossSectionBuilder, -# "crs": { -# "assign": og_gs.assign_section_geographic_coordinate_system_info, -# "convert": og_gs.convert_section_coordinate_reference_system, -# "create": og.create_section_coordinate_system, -# }, -# "object_type": model, -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_implicit_cross_section, -# "save_light_viewable": g_v.save_light_viewable_implicit_cross_section, -# "inspector": og_inspector.inspect_section, -# }, -# "ImplicitStructuralModel": { -# "parent": "StructuralModel", -# "class": og_gs.ImplicitStructuralModel, -# "input_factory": og_gs.ImplicitStructuralModelInputFactory, -# "output_factory": og_gs.ImplicitStructuralModelOutputFactory, -# "additional_files": og_gs.implicit_structural_model_additional_files, -# "is_loadable": og_gs.is_implicit_structural_model_loadable, -# "object_priority": og_gs.implicit_structural_model_object_priority, -# "load": og_gs.load_implicit_structural_model, -# "is_saveable": og_gs.is_implicit_structural_model_saveable, -# "save": og_gs.save_implicit_structural_model, -# "builder": og_gs.ImplicitStructuralModelBuilder, -# "crs": { -# "assign": og_gs.assign_brep_geographic_coordinate_system_info, -# "convert": og_gs.convert_brep_coordinate_reference_system, -# "create": og.create_brep_coordinate_system, -# }, -# "object_type": model, -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_implicit_structural_model, -# "save_light_viewable": g_v.save_light_viewable_implicit_structural_model, -# "inspector": og_inspector.inspect_brep, -# }, -# "LightRegularGrid2D": { -# "class": og.LightRegularGrid2D, -# "input_factory": og.LightRegularGridInputFactory2D, -# "output_factory": og.LightRegularGridOutputFactory2D, -# "additional_files": og.light_regular_grid_additional_files2D, -# "is_loadable": og.is_light_regular_grid_loadable2D, -# "object_priority": og.light_regular_grid_object_priority2D, -# "load": og.load_light_regular_grid2D, -# "is_saveable": og.is_light_regular_grid_saveable2D, -# "save": og.save_light_regular_grid2D, -# "object_type": mesh, -# "elements": [points, polygons], -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_light_regular_grid2D, -# "save_light_viewable": g_v.save_light_viewable_light_regular_grid2D, -# }, -# "LightRegularGrid3D": { -# "class": og.LightRegularGrid3D, -# "input_factory": og.LightRegularGridInputFactory3D, -# "output_factory": og.LightRegularGridOutputFactory3D, -# "additional_files": og.light_regular_grid_additional_files3D, -# "is_loadable": og.is_light_regular_grid_loadable3D, -# "object_priority": og.light_regular_grid_object_priority3D, -# "load": og.load_light_regular_grid3D, -# "is_saveable": og.is_light_regular_grid_saveable3D, -# "save": og.save_light_regular_grid3D, -# "object_type": mesh, -# "elements": [points, polyhedrons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_light_regular_grid3D, -# "save_light_viewable": g_v.save_light_viewable_light_regular_grid3D, -# }, -# "PointSet2D": { -# "class": og.PointSet2D, -# "input_factory": og.PointSetInputFactory2D, -# "output_factory": og.PointSetOutputFactory2D, -# "additional_files": og.point_set_additional_files2D, -# "is_loadable": og.is_point_set_loadable2D, -# "object_priority": og.point_set_object_priority2D, -# "load": og.load_point_set2D, -# "is_saveable": og.is_point_set_saveable2D, -# "save": og.save_point_set2D, -# "builder": og.PointSetBuilder2D.create, -# "crs": { -# "assign": og_gs.assign_point_set_geographic_coordinate_system_info2D, -# "convert": og_gs.convert_point_set_coordinate_reference_system2D, -# "create": og.create_point_set_coordinate_system2D, -# }, -# "object_type": mesh, -# "elements": [points], -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_point_set2D, -# "save_light_viewable": g_v.save_light_viewable_point_set2D, -# "inspector": og_inspector.inspect_point_set2D, -# }, -# "PointSet3D": { -# "class": og.PointSet3D, -# "input_factory": og.PointSetInputFactory3D, -# "output_factory": og.PointSetOutputFactory3D, -# "additional_files": og.point_set_additional_files3D, -# "is_loadable": og.is_point_set_loadable3D, -# "object_priority": og.point_set_object_priority3D, -# "load": og.load_point_set3D, -# "is_saveable": og.is_point_set_saveable3D, -# "save": og.save_point_set3D, -# "builder": og.PointSetBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_point_set_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_point_set_coordinate_reference_system3D, -# "create": og.create_point_set_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_point_set3D, -# "save_light_viewable": g_v.save_light_viewable_point_set3D, -# "inspector": og_inspector.inspect_point_set3D, -# }, -# "PolygonalSurface2D": { -# "class": og.PolygonalSurface2D, -# "input_factory": og.PolygonalSurfaceInputFactory2D, -# "output_factory": og.PolygonalSurfaceOutputFactory2D, -# "additional_files": og.polygonal_surface_additional_files2D, -# "is_loadable": og.is_polygonal_surface_loadable2D, -# "object_priority": og.polygonal_surface_object_priority2D, -# "load": og.load_polygonal_surface2D, -# "is_saveable": og.is_polygonal_surface_saveable2D, -# "save": og.save_polygonal_surface2D, -# "builder": og.PolygonalSurfaceBuilder2D.create, -# "crs": { -# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, -# "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, -# "create": og.create_surface_mesh_coordinate_system2D, -# }, -# "object_type": mesh, -# "elements": [points, polygons], -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_polygonal_surface2D, -# "save_light_viewable": g_v.save_light_viewable_polygonal_surface2D, -# "inspector": og_inspector.inspect_surface2D, -# }, -# "PolygonalSurface3D": { -# "class": og.PolygonalSurface3D, -# "input_factory": og.PolygonalSurfaceInputFactory3D, -# "output_factory": og.PolygonalSurfaceOutputFactory3D, -# "additional_files": og.polygonal_surface_additional_files3D, -# "is_loadable": og.is_polygonal_surface_loadable3D, -# "object_priority": og.polygonal_surface_object_priority3D, -# "load": og.load_polygonal_surface3D, -# "is_saveable": og.is_polygonal_surface_saveable3D, -# "save": og.save_polygonal_surface3D, -# "builder": og.PolygonalSurfaceBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_surface_mesh_coordinate_reference_system3D, -# "create": og.create_surface_mesh_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points, polygons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_polygonal_surface3D, -# "save_light_viewable": g_v.save_light_viewable_polygonal_surface3D, -# "inspector": og_inspector.inspect_surface3D, -# }, -# "PolyhedralSolid3D": { -# "class": og.PolyhedralSolid3D, -# "input_factory": og.PolyhedralSolidInputFactory3D, -# "output_factory": og.PolyhedralSolidOutputFactory3D, -# "additional_files": og.polyhedral_solid_additional_files3D, -# "is_loadable": og.is_polyhedral_solid_loadable3D, -# "object_priority": og.polyhedral_solid_object_priority3D, -# "load": og.load_polyhedral_solid3D, -# "is_saveable": og.is_polyhedral_solid_saveable3D, -# "save": og.save_polyhedral_solid3D, -# "builder": og.PolyhedralSolidBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, -# "create": og.create_solid_mesh_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points, polyhedrons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_polyhedral_solid3D, -# "save_light_viewable": g_v.save_light_viewable_polyhedral_solid3D, -# "inspector": og_inspector.inspect_solid3D, -# }, -# "RasterImage2D": { -# "class": og.RasterImage2D, -# "input_factory": og.RasterImageInputFactory2D, -# "output_factory": og.RasterImageOutputFactory2D, -# "additional_files": og.raster_image_additional_files2D, -# "is_loadable": og.is_raster_image_loadable2D, -# "object_priority": og.raster_image_object_priority2D, -# "load": og.load_raster_image2D, -# "is_saveable": og.is_raster_image_saveable2D, -# "save": og.save_raster_image2D, -# "object_type": mesh, -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_raster_image2D, -# }, -# "RasterImage3D": { -# "class": og.RasterImage3D, -# "input_factory": og.RasterImageInputFactory3D, -# "output_factory": og.RasterImageOutputFactory3D, -# "additional_files": og.raster_image_additional_files3D, -# "is_loadable": og.is_raster_image_loadable3D, -# "object_priority": og.raster_image_object_priority3D, -# "load": og.load_raster_image3D, -# "is_saveable": og.is_raster_image_saveable3D, -# "save": og.save_raster_image3D, -# "object_type": mesh, -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_raster_image3D, -# }, -# "RegularGrid2D": { -# "class": og.RegularGrid2D, -# "input_factory": og.RegularGridInputFactory2D, -# "output_factory": og.RegularGridOutputFactory2D, -# "additional_files": og.regular_grid_additional_files2D, -# "is_loadable": og.is_regular_grid_loadable2D, -# "object_priority": og.regular_grid_object_priority2D, -# "load": og.load_regular_grid2D, -# "is_saveable": og.is_regular_grid_saveable2D, -# "save": og.save_regular_grid2D, -# "builder": og.RegularGridBuilder2D.create, -# "crs": { -# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, -# "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, -# "create": og.create_surface_mesh_coordinate_system2D, -# }, -# "object_type": mesh, -# "elements": [points, polygons], -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_regular_grid2D, -# "save_light_viewable": g_v.save_light_viewable_regular_grid2D, -# }, -# "RegularGrid3D": { -# "class": og.RegularGrid3D, -# "input_factory": og.RegularGridInputFactory3D, -# "output_factory": og.RegularGridOutputFactory3D, -# "additional_files": og.regular_grid_additional_files3D, -# "is_loadable": og.is_regular_grid_loadable3D, -# "object_priority": og.regular_grid_object_priority3D, -# "load": og.load_regular_grid3D, -# "is_saveable": og.is_regular_grid_saveable3D, -# "save": og.save_regular_grid3D, -# "builder": og.RegularGridBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, -# "create": og.create_surface_mesh_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points, polyhedrons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_regular_grid3D, -# "save_light_viewable": g_v.save_light_viewable_regular_grid3D, -# }, -# "Section": { -# "class": og.Section, -# "input_factory": og.SectionInputFactory, -# "output_factory": og.SectionOutputFactory, -# "additional_files": og.section_additional_files, -# "is_loadable": og.is_section_loadable, -# "object_priority": og.section_object_priority, -# "load": og.load_section, -# "is_saveable": og.is_section_saveable, -# "save": og.save_section, -# "builder": og.SectionBuilder, -# "crs": { -# "assign": og_gs.assign_section_geographic_coordinate_system_info, -# "convert": og_gs.convert_section_coordinate_reference_system, -# "create": og.create_section_coordinate_system, -# }, -# "object_type": model, -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_section, -# "save_light_viewable": g_v.save_light_viewable_section, -# "inspector": og_inspector.inspect_section, -# }, -# "StructuralModel": { -# "parent": "BRep", -# "class": og_gs.StructuralModel, -# "input_factory": og_gs.StructuralModelInputFactory, -# "output_factory": og_gs.StructuralModelOutputFactory, -# "additional_files": og_gs.structural_model_additional_files, -# "is_loadable": og_gs.is_structural_model_loadable, -# "object_priority": og_gs.structural_model_object_priority, -# "load": og_gs.load_structural_model, -# "is_saveable": og_gs.is_structural_model_saveable, -# "save": og_gs.save_structural_model, -# "builder": og_gs.StructuralModelBuilder, -# "crs": { -# "assign": og_gs.assign_brep_geographic_coordinate_system_info, -# "convert": og_gs.convert_brep_coordinate_reference_system, -# "create": og.create_brep_coordinate_system, -# }, -# "object_type": model, -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_structural_model, -# "save_light_viewable": g_v.save_light_viewable_structural_model, -# "inspector": og_inspector.inspect_brep, -# }, -# "TetrahedralSolid3D": { -# "class": og.TetrahedralSolid3D, -# "input_factory": og.TetrahedralSolidInputFactory3D, -# "output_factory": og.TetrahedralSolidOutputFactory3D, -# "additional_files": og.tetrahedral_solid_additional_files3D, -# "is_loadable": og.is_tetrahedral_solid_loadable3D, -# "object_priority": og.tetrahedral_solid_object_priority3D, -# "load": og.load_tetrahedral_solid3D, -# "is_saveable": og.is_tetrahedral_solid_saveable3D, -# "save": og.save_tetrahedral_solid3D, -# "builder": og.TetrahedralSolidBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_solid_mesh_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_solid_mesh_coordinate_reference_system3D, -# "create": og.create_solid_mesh_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points, polyhedrons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_tetrahedral_solid3D, -# "save_light_viewable": g_v.save_light_viewable_tetrahedral_solid3D, -# "inspector": og_inspector.inspect_solid3D, -# }, -# "TriangulatedSurface2D": { -# "class": og.TriangulatedSurface2D, -# "input_factory": og.TriangulatedSurfaceInputFactory2D, -# "output_factory": og.TriangulatedSurfaceOutputFactory2D, -# "additional_files": og.triangulated_surface_additional_files2D, -# "is_loadable": og.is_triangulated_surface_loadable2D, -# "object_priority": og.triangulated_surface_object_priority2D, -# "load": og.load_triangulated_surface2D, -# "is_saveable": og.is_triangulated_surface_saveable2D, -# "save": og.save_triangulated_surface2D, -# "builder": og.TriangulatedSurfaceBuilder2D.create, -# "crs": { -# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info2D, -# "convert": og_gs.convert_surface_mesh_coordinate_reference_system2D, -# "create": og.create_surface_mesh_coordinate_system2D, -# }, -# "object_type": mesh, -# "elements": [points, polygons], -# "is_3D": False, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_triangulated_surface2D, -# "save_light_viewable": g_v.save_light_viewable_triangulated_surface2D, -# "inspector": og_inspector.inspect_surface2D, -# }, -# "TriangulatedSurface3D": { -# "class": og.TriangulatedSurface3D, -# "input_factory": og.TriangulatedSurfaceInputFactory3D, -# "output_factory": og.TriangulatedSurfaceOutputFactory3D, -# "additional_files": og.triangulated_surface_additional_files3D, -# "is_loadable": og.is_triangulated_surface_loadable3D, -# "object_priority": og.triangulated_surface_object_priority3D, -# "load": og.load_triangulated_surface3D, -# "is_saveable": og.is_triangulated_surface_saveable3D, -# "save": og.save_triangulated_surface3D, -# "builder": og.TriangulatedSurfaceBuilder3D.create, -# "crs": { -# "assign": og_gs.assign_surface_mesh_geographic_coordinate_system_info3D, -# "convert": og_gs.convert_surface_mesh_coordinate_reference_system3D, -# "create": og.create_surface_mesh_coordinate_system3D, -# }, -# "object_type": mesh, -# "elements": [points, polygons], -# "is_3D": True, -# "is_viewable": True, -# "save_viewable": g_v.save_viewable_triangulated_surface3D, -# "save_light_viewable": g_v.save_light_viewable_triangulated_surface3D, -# "inspector": og_inspector.inspect_surface3D, -# }, -# "VertexSet": { -# "class": og.VertexSet, -# "input_factory": og.VertexSetInputFactory, -# "output_factory": og.VertexSetOutputFactory, -# "additional_files": og.vertex_set_additional_files, -# "is_loadable": og.is_vertex_set_loadable, -# "object_priority": og.vertex_set_object_priority, -# "load": og.load_vertex_set, -# "is_saveable": og.is_vertex_set_saveable, -# "save": og.save_vertex_set, -# "builder": og.VertexSetBuilder.create, -# "object_type": mesh, -# "is_3D": False, -# "is_viewable": False, -# }, -# } diff --git a/src/opengeodeweb_back/geode_objects/geode_point_set2d.py b/src/opengeodeweb_back/geode_objects/geode_point_set2d.py index 87c04724..2a35b97a 100644 --- a/src/opengeodeweb_back/geode_objects/geode_point_set2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_point_set2d.py @@ -16,11 +16,11 @@ class GeodePointSet2D(GeodeVertexSet): point_set: og.PointSet2D def __init__(self, point_set: og.PointSet2D | None = None) -> None: - self.point_set = point_set if point_set is not None else og.PointSet2D() + self.point_set = point_set if point_set is not None else og.PointSet2D.create() super().__init__(self.point_set) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "PointSet2D" def native_extension(self) -> str: @@ -35,10 +35,10 @@ def is_viewable(cls) -> bool: return True def builder(self) -> og.PointSetBuilder2D: - return og.PointSetBuilder2D(self.point_set) + return og.PointSetBuilder2D.create(self.point_set) @classmethod - def load_mesh(cls, filename: str) -> GeodePointSet2D: + def load(cls, filename: str) -> GeodePointSet2D: return GeodePointSet2D(og.load_point_set2D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_point_set3d.py b/src/opengeodeweb_back/geode_objects/geode_point_set3d.py index d2e1b921..1c490b59 100644 --- a/src/opengeodeweb_back/geode_objects/geode_point_set3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_point_set3d.py @@ -16,11 +16,11 @@ class GeodePointSet3D(GeodeVertexSet): point_set: og.PointSet3D def __init__(self, point_set: og.PointSet3D | None = None) -> None: - self.point_set = point_set if point_set is not None else og.PointSet3D() + self.point_set = point_set if point_set is not None else og.PointSet3D.create() super().__init__(self.point_set) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "PointSet3D" def native_extension(self) -> str: @@ -35,10 +35,10 @@ def is_viewable(cls) -> bool: return True def builder(self) -> og.PointSetBuilder3D: - return og.PointSetBuilder3D(self.point_set) + return og.PointSetBuilder3D.create(self.point_set) @classmethod - def load_mesh(cls, filename: str) -> GeodePointSet3D: + def load(cls, filename: str) -> GeodePointSet3D: return GeodePointSet3D(og.load_point_set3D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_polygonal_surface2d.py b/src/opengeodeweb_back/geode_objects/geode_polygonal_surface2d.py index 899d5541..6ff30f5a 100644 --- a/src/opengeodeweb_back/geode_objects/geode_polygonal_surface2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_polygonal_surface2d.py @@ -18,22 +18,22 @@ def __init__(self, polygonal_surface: og.PolygonalSurface2D | None = None) -> No self.polygonal_surface = ( polygonal_surface if polygonal_surface is not None - else og.PolygonalSurface2D() + else og.PolygonalSurface2D.create() ) super().__init__(self.polygonal_surface) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "PolygonalSurface2D" def native_extension(self) -> str: return self.polygonal_surface.native_extension() def builder(self) -> og.PolygonalSurfaceBuilder2D: - return og.PolygonalSurfaceBuilder2D(self.polygonal_surface) + return og.PolygonalSurfaceBuilder2D.create(self.polygonal_surface) @classmethod - def load_mesh(cls, filename: str) -> GeodePolygonalSurface2D: + def load(cls, filename: str) -> GeodePolygonalSurface2D: return GeodePolygonalSurface2D(og.load_polygonal_surface2D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_polygonal_surface3d.py b/src/opengeodeweb_back/geode_objects/geode_polygonal_surface3d.py index 4cba25e3..48438d53 100644 --- a/src/opengeodeweb_back/geode_objects/geode_polygonal_surface3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_polygonal_surface3d.py @@ -18,22 +18,22 @@ def __init__(self, polygonal_surface: og.PolygonalSurface3D | None = None) -> No self.polygonal_surface = ( polygonal_surface if polygonal_surface is not None - else og.PolygonalSurface3D() + else og.PolygonalSurface3D.create() ) super().__init__(self.polygonal_surface) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "PolygonalSurface3D" def native_extension(self) -> str: return self.polygonal_surface.native_extension() def builder(self) -> og.PolygonalSurfaceBuilder3D: - return og.PolygonalSurfaceBuilder3D(self.polygonal_surface) + return og.PolygonalSurfaceBuilder3D.create(self.polygonal_surface) @classmethod - def load_mesh(cls, filename: str) -> GeodePolygonalSurface3D: + def load(cls, filename: str) -> GeodePolygonalSurface3D: return GeodePolygonalSurface3D(og.load_polygonal_surface3D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_polyhedral_solid3d.py b/src/opengeodeweb_back/geode_objects/geode_polyhedral_solid3d.py index c76199c4..140dd324 100644 --- a/src/opengeodeweb_back/geode_objects/geode_polyhedral_solid3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_polyhedral_solid3d.py @@ -16,22 +16,24 @@ class GeodePolyhedralSolid3D(GeodeSolidMesh3D): def __init__(self, polyhedral_solid: og.PolyhedralSolid3D | None = None) -> None: self.polyhedral_solid = ( - polyhedral_solid if polyhedral_solid is not None else og.PolyhedralSolid3D() + polyhedral_solid + if polyhedral_solid is not None + else og.PolyhedralSolid3D.create() ) super().__init__(self.polyhedral_solid) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "PolyhedralSolid3D" def native_extension(self) -> str: return self.polyhedral_solid.native_extension() def builder(self) -> og.PolyhedralSolidBuilder3D: - return og.PolyhedralSolidBuilder3D(self.polyhedral_solid) + return og.PolyhedralSolidBuilder3D.create(self.polyhedral_solid) @classmethod - def load_mesh(cls, filename: str) -> GeodePolyhedralSolid3D: + def load(cls, filename: str) -> GeodePolyhedralSolid3D: return GeodePolyhedralSolid3D(og.load_polyhedral_solid3D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py b/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py index 8f5dbeac..c7201df0 100644 --- a/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py @@ -19,7 +19,7 @@ def __init__(self, raster_image: og.RasterImage2D) -> None: super().__init__(self.raster_image) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "RasterImage2D" def native_extension(self) -> str: @@ -37,7 +37,7 @@ def builder(self) -> None: return None @classmethod - def load_mesh(cls, filename: str) -> GeodeRasterImage2D: + def load(cls, filename: str) -> GeodeRasterImage2D: return GeodeRasterImage2D(og.load_raster_image2D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py b/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py index a8f75760..a6fb8555 100644 --- a/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py @@ -19,7 +19,7 @@ def __init__(self, raster_image: og.RasterImage3D) -> None: super().__init__(self.raster_image) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "RasterImage3D" def native_extension(self) -> str: @@ -37,7 +37,7 @@ def builder(self) -> None: return None @classmethod - def load_mesh(cls, filename: str) -> GeodeRasterImage3D: + def load(cls, filename: str) -> GeodeRasterImage3D: return GeodeRasterImage3D(og.load_raster_image3D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py b/src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py index 5bc8a3ce..e16c093c 100644 --- a/src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py @@ -16,22 +16,22 @@ class GeodeRegularGrid2D(GeodeSurfaceMesh2D): def __init__(self, regular_grid: og.RegularGrid2D | None = None) -> None: self.regular_grid = ( - regular_grid if regular_grid is not None else og.RegularGrid2D() + regular_grid if regular_grid is not None else og.RegularGrid2D.create() ) super().__init__(self.regular_grid) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "RegularGrid2D" def native_extension(self) -> str: return self.regular_grid.native_extension() def builder(self) -> og.RegularGridBuilder2D: - return og.RegularGridBuilder2D(self.regular_grid) + return og.RegularGridBuilder2D.create(self.regular_grid) @classmethod - def load_mesh(cls, filename: str) -> GeodeRegularGrid2D: + def load(cls, filename: str) -> GeodeRegularGrid2D: return GeodeRegularGrid2D(og.load_regular_grid2D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_regulard_grid3d.py b/src/opengeodeweb_back/geode_objects/geode_regulard_grid3d.py index 628e6167..7ed0d6c0 100644 --- a/src/opengeodeweb_back/geode_objects/geode_regulard_grid3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_regulard_grid3d.py @@ -16,22 +16,22 @@ class GeodeRegularGrid3D(GeodeSolidMesh3D): def __init__(self, regular_grid: og.RegularGrid3D | None = None) -> None: self.regular_grid = ( - regular_grid if regular_grid is not None else og.RegularGrid3D() + regular_grid if regular_grid is not None else og.RegularGrid3D.create() ) super().__init__(self.regular_grid) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "RegularGrid3D" def native_extension(self) -> str: return self.regular_grid.native_extension() def builder(self) -> og.RegularGridBuilder3D: - return og.RegularGridBuilder3D(self.regular_grid) + return og.RegularGridBuilder3D.create(self.regular_grid) @classmethod - def load_mesh(cls, filename: str) -> GeodeRegularGrid3D: + def load(cls, filename: str) -> GeodeRegularGrid3D: return GeodeRegularGrid3D(og.load_regular_grid3D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_section.py b/src/opengeodeweb_back/geode_objects/geode_section.py index 75780ba3..a848673b 100644 --- a/src/opengeodeweb_back/geode_objects/geode_section.py +++ b/src/opengeodeweb_back/geode_objects/geode_section.py @@ -20,7 +20,7 @@ def __init__(self, section: og.Section | None = None) -> None: super().__init__(self.section) @classmethod - def geode_model_type(cls) -> GeodeModelType: + def geode_object_type(cls) -> GeodeModelType: return "Section" def native_extension(self) -> str: @@ -38,7 +38,7 @@ def builder(self) -> og.SectionBuilder: return og.SectionBuilder(self.section) @classmethod - def load_model(cls, filename: str) -> GeodeSection: + def load(cls, filename: str) -> GeodeSection: return GeodeSection(og.load_section(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_solid_mesh3d.py b/src/opengeodeweb_back/geode_objects/geode_solid_mesh3d.py index 35be5e6d..7842bcc8 100644 --- a/src/opengeodeweb_back/geode_objects/geode_solid_mesh3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_solid_mesh3d.py @@ -56,3 +56,6 @@ def create_crs( og.create_solid_mesh_coordinate_system3D( self.solid_mesh, builder, crs_name, input, output ) + + def polyhedron_attribute_manager(self) -> og.AttributeManager: + return self.solid_mesh.polyhedron_attribute_manager() diff --git a/src/opengeodeweb_back/geode_objects/geode_structural_model.py b/src/opengeodeweb_back/geode_objects/geode_structural_model.py index fa104f0d..74b28fc8 100644 --- a/src/opengeodeweb_back/geode_objects/geode_structural_model.py +++ b/src/opengeodeweb_back/geode_objects/geode_structural_model.py @@ -26,7 +26,7 @@ def __init__( super().__init__(self.structural_model) @classmethod - def geode_model_type(cls) -> GeodeModelType: + def geode_object_type(cls) -> GeodeModelType: return "StructuralModel" def native_extension(self) -> str: @@ -36,7 +36,7 @@ def builder(self) -> og_geosciences.StructuralModelBuilder: return og_geosciences.StructuralModelBuilder(self.structural_model) @classmethod - def load_model(cls, filename: str) -> GeodeStructuralModel: + def load(cls, filename: str) -> GeodeStructuralModel: return GeodeStructuralModel(og_geosciences.load_structural_model(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_surface_mesh2d.py b/src/opengeodeweb_back/geode_objects/geode_surface_mesh2d.py index d86ee6ee..dd49135e 100644 --- a/src/opengeodeweb_back/geode_objects/geode_surface_mesh2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_surface_mesh2d.py @@ -17,7 +17,7 @@ class GeodeSurfaceMesh2D(GeodeVertexSet): def __init__(self, surface_mesh: og.SurfaceMesh2D | None = None) -> None: self.surface_mesh = ( - surface_mesh if surface_mesh is not None else og.SurfaceMesh2D() + surface_mesh if surface_mesh is not None else og.SurfaceMesh2D.create() ) super().__init__(self.surface_mesh) @@ -58,3 +58,9 @@ def create_crs( og.create_surface_mesh_coordinate_system2D( self.surface_mesh, builder, crs_name, input, output ) + + def polygon_attribute_manager(self) -> og.AttributeManager: + return self.surface_mesh.polygon_attribute_manager() + + def texture_manager(self) -> og.TextureManager2D: + return self.surface_mesh.texture_manager() diff --git a/src/opengeodeweb_back/geode_objects/geode_surface_mesh3d.py b/src/opengeodeweb_back/geode_objects/geode_surface_mesh3d.py index a635ba15..d064f885 100644 --- a/src/opengeodeweb_back/geode_objects/geode_surface_mesh3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_surface_mesh3d.py @@ -17,7 +17,7 @@ class GeodeSurfaceMesh3D(GeodeVertexSet): def __init__(self, surface_mesh: og.SurfaceMesh3D | None = None) -> None: self.surface_mesh = ( - surface_mesh if surface_mesh is not None else og.SurfaceMesh3D() + surface_mesh if surface_mesh is not None else og.SurfaceMesh3D.create() ) super().__init__(self.surface_mesh) @@ -58,3 +58,9 @@ def create_crs( og.create_surface_mesh_coordinate_system3D( self.surface_mesh, builder, crs_name, input, output ) + + def polygon_attribute_manager(self) -> og.AttributeManager: + return self.surface_mesh.polygon_attribute_manager() + + def texture_manager(self) -> og.TextureManager2D: + return self.surface_mesh.texture_manager() diff --git a/src/opengeodeweb_back/geode_objects/geode_tetrahedral_solid3d.py b/src/opengeodeweb_back/geode_objects/geode_tetrahedral_solid3d.py index 15dc10c2..d1b95f02 100644 --- a/src/opengeodeweb_back/geode_objects/geode_tetrahedral_solid3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_tetrahedral_solid3d.py @@ -18,22 +18,22 @@ def __init__(self, tetrahedral_solid: og.TetrahedralSolid3D | None = None) -> No self.tetrahedral_solid = ( tetrahedral_solid if tetrahedral_solid is not None - else og.TetrahedralSolid3D() + else og.TetrahedralSolid3D.create() ) super().__init__(self.tetrahedral_solid) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "TetrahedralSolid3D" def native_extension(self) -> str: return self.tetrahedral_solid.native_extension() def builder(self) -> og.TetrahedralSolidBuilder3D: - return og.TetrahedralSolidBuilder3D(self.tetrahedral_solid) + return og.TetrahedralSolidBuilder3D.create(self.tetrahedral_solid) @classmethod - def load_mesh(cls, filename: str) -> GeodeTetrahedralSolid3D: + def load(cls, filename: str) -> GeodeTetrahedralSolid3D: return GeodeTetrahedralSolid3D(og.load_tetrahedral_solid3D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_triangulated_surface2d.py b/src/opengeodeweb_back/geode_objects/geode_triangulated_surface2d.py index 9e0558ee..8363cd38 100644 --- a/src/opengeodeweb_back/geode_objects/geode_triangulated_surface2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_triangulated_surface2d.py @@ -20,22 +20,22 @@ def __init__( self.triangulated_surface = ( triangulated_surface if triangulated_surface is not None - else og.TriangulatedSurface2D() + else og.TriangulatedSurface2D.create() ) super().__init__(self.triangulated_surface) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "TriangulatedSurface2D" def native_extension(self) -> str: return self.triangulated_surface.native_extension() def builder(self) -> og.TriangulatedSurfaceBuilder2D: - return og.TriangulatedSurfaceBuilder2D(self.triangulated_surface) + return og.TriangulatedSurfaceBuilder2D.create(self.triangulated_surface) @classmethod - def load_mesh(cls, filename: str) -> GeodeTriangulatedSurface2D: + def load(cls, filename: str) -> GeodeTriangulatedSurface2D: return GeodeTriangulatedSurface2D(og.load_triangulated_surface2D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_triangulated_surface3d.py b/src/opengeodeweb_back/geode_objects/geode_triangulated_surface3d.py index d5b3e81c..b34d6487 100644 --- a/src/opengeodeweb_back/geode_objects/geode_triangulated_surface3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_triangulated_surface3d.py @@ -20,22 +20,22 @@ def __init__( self.triangulated_surface = ( triangulated_surface if triangulated_surface is not None - else og.TriangulatedSurface3D() + else og.TriangulatedSurface3D.create() ) super().__init__(self.triangulated_surface) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "TriangulatedSurface3D" def native_extension(self) -> str: return self.triangulated_surface.native_extension() def builder(self) -> og.TriangulatedSurfaceBuilder3D: - return og.TriangulatedSurfaceBuilder3D(self.triangulated_surface) + return og.TriangulatedSurfaceBuilder3D.create(self.triangulated_surface) @classmethod - def load_mesh(cls, filename: str) -> GeodeTriangulatedSurface3D: + def load(cls, filename: str) -> GeodeTriangulatedSurface3D: return GeodeTriangulatedSurface3D(og.load_triangulated_surface3D(filename)) @classmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_vertex_set.py b/src/opengeodeweb_back/geode_objects/geode_vertex_set.py index 7c1a1a93..0cf9028f 100644 --- a/src/opengeodeweb_back/geode_objects/geode_vertex_set.py +++ b/src/opengeodeweb_back/geode_objects/geode_vertex_set.py @@ -15,11 +15,13 @@ class GeodeVertexSet(GeodeMesh): vertex_set: og.VertexSet def __init__(self, vertex_set: og.VertexSet | None = None) -> None: - self.vertex_set = vertex_set if vertex_set is not None else og.VertexSet() + self.vertex_set = ( + vertex_set if vertex_set is not None else og.VertexSet.create() + ) super().__init__(self.vertex_set) @classmethod - def geode_mesh_type(cls) -> GeodeMeshType: + def geode_object_type(cls) -> GeodeMeshType: return "VertexSet" def native_extension(self) -> str: @@ -34,10 +36,10 @@ def is_viewable(cls) -> bool: return False def builder(self) -> og.VertexSetBuilder: - return og.VertexSetBuilder(self.vertex_set) + return og.VertexSetBuilder.create(self.vertex_set) @classmethod - def load_mesh(cls, filename: str) -> GeodeVertexSet: + def load(cls, filename: str) -> GeodeVertexSet: return GeodeVertexSet(og.load_vertex_set(filename)) @classmethod @@ -74,3 +76,6 @@ def save_light_viewable(self, filename_without_extension: str) -> str: def inspect(self) -> object: return None + + def vertex_attribute_manager(self) -> og.AttributeManager: + return self.vertex_set.vertex_attribute_manager() diff --git a/src/opengeodeweb_back/geode_objects/types.py b/src/opengeodeweb_back/geode_objects/types.py index 943f3856..f42fed08 100644 --- a/src/opengeodeweb_back/geode_objects/types.py +++ b/src/opengeodeweb_back/geode_objects/types.py @@ -6,38 +6,27 @@ # Local application imports -GeodeSurfaceMeshType = Literal[ +GeodeMeshType = Literal[ + "VertexSet", + "Graph", + "PointSet2D", + "PointSet3D", + "EdgedCurve2D", + "EdgedCurve3D", + "RasterImage2D", + "RasterImage3D", "PolygonalSurface2D", "PolygonalSurface3D", "TriangulatedSurface2D", "TriangulatedSurface3D", "RegularGrid2D", -] -GeodeSolidMeshType = Literal[ "PolyhedralSolid3D", "TetrahedralSolid3D", "HybridSolid3D", "RegularGrid3D", -] -GeodeGridType = Literal[ "LightRegularGrid2D", "LightRegularGrid3D", ] -GeodeMeshType = ( - Literal[ - "VertexSet", - "Graph", - "PointSet2D", - "PointSet3D", - "EdgedCurve2D", - "EdgedCurve3D", - "RasterImage2D", - "RasterImage3D", - ] - | GeodeSurfaceMeshType - | GeodeSolidMeshType - | GeodeGridType -) GeodeModelType = Literal[ "BRep", "Section", @@ -59,11 +48,6 @@ def _flatten_literal_args(literal: object) -> tuple[str, ...]: return tuple(flattened) -GeodeSurfaceMeshType_values = _flatten_literal_args(GeodeSurfaceMeshType) -GeodeSolidMeshType_values = _flatten_literal_args(GeodeSolidMeshType) -GeodeGridType_values = _flatten_literal_args(GeodeGridType) -GeodeMeshType_values = _flatten_literal_args(GeodeMeshType) -GeodeModelType_values = _flatten_literal_args(GeodeModelType) GeodeObjectType_values = _flatten_literal_args(GeodeObjectType) @@ -75,36 +59,4 @@ def geode_object_type(value: str) -> GeodeObjectType: return cast(GeodeObjectType, value) -def geode_mesh_type(value: str) -> GeodeMeshType: - if value not in GeodeMeshType_values: - raise ValueError( - f"Invalid GeodeMeshType: {value!r}. Must be one of {GeodeMeshType_values}" - ) - return cast(GeodeMeshType, value) - - -def geode_surface_mesh_type(value: str) -> GeodeSurfaceMeshType: - if value not in GeodeSurfaceMeshType_values: - raise ValueError( - f"Invalid GeodeSurfaceMeshType: {value!r}. Must be one of {GeodeSurfaceMeshType_values}" - ) - return cast(GeodeSurfaceMeshType, value) - - -def geode_solid_mesh_type(value: str) -> GeodeSolidMeshType: - if value not in GeodeSolidMeshType_values: - raise ValueError( - f"Invalid GeodeSolidMeshType: {value!r}. Must be one of {GeodeSolidMeshType_values}" - ) - return cast(GeodeSolidMeshType, value) - - -def geode_model_type(value: str) -> GeodeModelType: - if value not in GeodeModelType_values: - raise ValueError( - f"Invalid GeodeModelType: {value!r}. Must be one of {GeodeModelType_values}" - ) - return cast(GeodeModelType, value) - - ViewerType = Literal["mesh", "model"] diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index 69e8e0a2..b8930ed0 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -20,6 +20,10 @@ from opengeodeweb_back import geode_functions, utils_functions from opengeodeweb_back.geode_objects import geode_objects from opengeodeweb_back.geode_objects.types import geode_object_type +from opengeodeweb_back.geode_objects.geode_mesh import GeodeMesh +from opengeodeweb_back.geode_objects.geode_surface_mesh2d import GeodeSurfaceMesh2D +from opengeodeweb_back.geode_objects.geode_surface_mesh3d import GeodeSurfaceMesh3D +from opengeodeweb_back.geode_objects.geode_solid_mesh3d import GeodeSolidMesh3D routes = flask.Blueprint("routes", __name__, url_prefix="/opengeodeweb_back") @@ -44,7 +48,7 @@ def allowed_files() -> flask.Response: for geode_object in geode_objects.values(): for extension in geode_object.input_extensions(): extensions.add(extension) - return flask.make_response({"extensions": extensions}, 200) + return flask.make_response({"extensions": list(extensions)}, 200) @routes.route( @@ -79,8 +83,8 @@ def allowed_objects() -> flask.Response: continue loadability_score = geode_object.is_loadable(file_absolute_path) priority_score = geode_object.object_priority(file_absolute_path) - allowed_objects[geode_object] = { - "is_loadable": loadability_score, + allowed_objects[geode_object_type] = { + "is_loadable": loadability_score.value(), "object_priority": priority_score, } return flask.make_response({"allowed_objects": allowed_objects}, 200) @@ -237,8 +241,10 @@ def save_viewable_file() -> flask.Response: def texture_coordinates() -> flask.Response: utils_functions.validate_request(flask.request, schemas_dict["texture_coordinates"]) params = schemas.TextureCoordinates.from_dict(flask.request.get_json()) - data = geode_functions.load_object_data(params.id) - texture_coordinates = data.texture_manager().texture_names() + geode_object = geode_functions.load_geode_object(params.id) + if not isinstance(geode_object, GeodeSurfaceMesh2D | GeodeSurfaceMesh3D): + flask.abort(500, f"{params.id} is not a GeodeSurfaceMesh") + texture_coordinates = geode_object.texture_manager().texture_names() return flask.make_response({"texture_coordinates": texture_coordinates}, 200) @@ -251,8 +257,10 @@ def vertex_attribute_names() -> flask.Response: flask.request, schemas_dict["vertex_attribute_names"] ) params = schemas.VertexAttributeNames.from_dict(flask.request.get_json()) - data = geode_functions.load_object_data(params.id) - vertex_attribute_names = data.vertex_attribute_manager().attribute_names() + geode_object = geode_functions.load_geode_object(params.id) + if not isinstance(geode_object, GeodeMesh): + flask.abort(500, f"{params.id} is not a GeodeMesh") + vertex_attribute_names = geode_object.vertex_attribute_manager().attribute_names() return flask.make_response( { "vertex_attribute_names": vertex_attribute_names, @@ -270,8 +278,10 @@ def polygon_attribute_names() -> flask.Response: flask.request, schemas_dict["polygon_attribute_names"] ) params = schemas.PolygonAttributeNames.from_dict(flask.request.get_json()) - data = geode_functions.load_object_data(params.id) - polygon_attribute_names = data.polygon_attribute_manager().attribute_names() + geode_object = geode_functions.load_geode_object(params.id) + if not isinstance(geode_object, GeodeSurfaceMesh2D | GeodeSurfaceMesh3D): + flask.abort(500, f"{params.id} is not a GeodeSurfaceMesh") + polygon_attribute_names = geode_object.polygon_attribute_manager().attribute_names() return flask.make_response( { "polygon_attribute_names": polygon_attribute_names, @@ -289,8 +299,12 @@ def polyhedron_attribute_names() -> flask.Response: flask.request, schemas_dict["polyhedron_attribute_names"] ) params = schemas.PolyhedronAttributeNames.from_dict(flask.request.get_json()) - data = geode_functions.load_object_data(params.id) - polyhedron_attribute_names = data.polyhedron_attribute_manager().attribute_names() + geode_object = geode_functions.load_geode_object(params.id) + if not isinstance(geode_object, GeodeSolidMesh3D): + flask.abort(500, f"{params.id} is not a GeodeSolidMesh") + polyhedron_attribute_names = ( + geode_object.polyhedron_attribute_manager().attribute_names() + ) return flask.make_response( { "polyhedron_attribute_names": polyhedron_attribute_names, diff --git a/src/opengeodeweb_back/routes/create/blueprint_create.py b/src/opengeodeweb_back/routes/create/blueprint_create.py index 3cfcd7ac..b9ad3b03 100644 --- a/src/opengeodeweb_back/routes/create/blueprint_create.py +++ b/src/opengeodeweb_back/routes/create/blueprint_create.py @@ -9,6 +9,8 @@ # Local application imports from opengeodeweb_back import geode_functions, utils_functions from . import schemas +from opengeodeweb_back.geode_objects.geode_point_set3d import GeodePointSet3D +from opengeodeweb_back.geode_objects.geode_edged_curve3d import GeodeEdgedCurve3D routes = flask.Blueprint("create", __name__, url_prefix="/create") schemas_dict = get_schemas_dict(os.path.join(os.path.dirname(__file__), "schemas")) @@ -24,15 +26,14 @@ def create_point() -> flask.Response: params = schemas.CreatePoint.from_dict(flask.request.get_json()) # Create the point - pointset = geode_functions.geode_object_class("PointSet3D").create() - builder = geode_functions.create_builder("PointSet3D", pointset) + pointset = GeodePointSet3D() + builder = pointset.builder() builder.set_name(params.name) builder.create_point(opengeode.Point3D([params.x, params.y, params.z])) # Save and get info result = utils_functions.generate_native_viewable_and_light_viewable_from_object( - geode_object="PointSet3D", - data=pointset, + pointset ) return flask.make_response(result, 200) @@ -46,8 +47,8 @@ def create_aoi() -> flask.Response: params = schemas.CreateAoi.from_dict(flask.request.get_json()) # Create the edged curve - edged_curve = geode_functions.geode_object_class("EdgedCurve3D").create() - builder = geode_functions.create_builder("EdgedCurve3D", edged_curve) + edged_curve = GeodeEdgedCurve3D() + builder = edged_curve.builder() builder.set_name(params.name) # Create vertices first @@ -62,8 +63,7 @@ def create_aoi() -> flask.Response: # Save and get info result = utils_functions.generate_native_viewable_and_light_viewable_from_object( - geode_object="EdgedCurve3D", - data=edged_curve, + edged_curve ) return flask.make_response(result, 200) @@ -78,24 +78,27 @@ def create_voi() -> flask.Response: aoi_data = geode_functions.get_data_info(params.aoi_id) if not aoi_data: - flask.abort(404, f"AOI with id {params.aoi_id} not found") + flask.abort(500, f"AOI with id {params.aoi_id} not found") - aoi_object = geode_functions.load_object_data(params.aoi_id) + aoi_object = geode_functions.load_geode_object(params.aoi_id) + if not isinstance(aoi_object, GeodeEdgedCurve3D): + flask.abort(500, f"AOI with id {params.aoi_id} not a GeodeEdgedCurve3D") - nb_points = aoi_object.nb_vertices() + aoi_curve = aoi_object.edged_curve + nb_points = aoi_curve.nb_vertices() - edged_curve = geode_functions.geode_object_class("EdgedCurve3D").create() - builder = geode_functions.create_builder("EdgedCurve3D", edged_curve) + edged_curve = GeodeEdgedCurve3D() + builder = edged_curve.builder() builder.set_name(params.name) for point_id in range(nb_points): - aoi_point = aoi_object.point(point_id) + aoi_point = aoi_curve.point(point_id) builder.create_point( opengeode.Point3D([aoi_point.value(0), aoi_point.value(1), params.z_min]) ) for point_id in range(nb_points): - aoi_point = aoi_object.point(point_id) + aoi_point = aoi_curve.point(point_id) builder.create_point( opengeode.Point3D([aoi_point.value(0), aoi_point.value(1), params.z_max]) ) @@ -107,7 +110,6 @@ def create_voi() -> flask.Response: builder.create_edge_with_vertices(point_id, point_id + nb_points) result = utils_functions.generate_native_viewable_and_light_viewable_from_object( - geode_object="EdgedCurve3D", - data=edged_curve, + edged_curve ) return flask.make_response(result, 200) diff --git a/src/opengeodeweb_back/routes/models/blueprint_models.py b/src/opengeodeweb_back/routes/models/blueprint_models.py index fbfb9c41..2b3ff7f5 100644 --- a/src/opengeodeweb_back/routes/models/blueprint_models.py +++ b/src/opengeodeweb_back/routes/models/blueprint_models.py @@ -4,6 +4,7 @@ from opengeodeweb_microservice.schemas import get_schemas_dict from opengeodeweb_back import geode_functions, utils_functions +from opengeodeweb_back.geode_objects.geode_model import GeodeModel from . import schemas routes = flask.Blueprint("models", __name__, url_prefix="/models") @@ -40,7 +41,9 @@ def uuid_to_flat_index() -> flask.Response: def extract_uuids_endpoint() -> flask.Response: utils_functions.validate_request(flask.request, schemas_dict["mesh_components"]) params = schemas.MeshComponents.from_dict(flask.request.get_json()) - model = geode_functions.load_model_data(params.id) + model = geode_functions.load_geode_object(params.id) + if not isinstance(model, GeodeModel): + flask.abort(500, f"{params.id} is not a GeodeModel") mesh_components = model.mesh_components() uuid_dict = {} for mesh_component, ids in mesh_components.items(): diff --git a/src/opengeodeweb_back/test_utils.py b/src/opengeodeweb_back/test_utils.py index 9f7d8355..f890989f 100644 --- a/src/opengeodeweb_back/test_utils.py +++ b/src/opengeodeweb_back/test_utils.py @@ -1,12 +1,12 @@ # Standard library imports -from typing import Callable +from typing import Callable, Any # Third party imports from flask.testing import FlaskClient # Local application imports -JsonData = dict[str, str] +JsonData = dict[str, Any] def test_route_wrong_params( diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index 6a88c31d..b4e7b23e 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -110,6 +110,7 @@ def validate_request(request: flask.Request, schema: SchemaDict) -> None: validate(json_data) except fastjsonschema.JsonSchemaException as e: error_msg = str(e) + print("Validation failed:", error_msg, flush=True) flask.abort(400, error_msg) @@ -185,7 +186,7 @@ def save_all_viewables_and_return_info( ) -> dict[str, str | list[str]]: with ThreadPoolExecutor() as executor: (native_files, viewable_path, light_path) = executor.map( - lambda func_path: func_path[0](), + lambda args: args[0](args[1]), [ ( geode_object.save, diff --git a/tests/test_create_routes.py b/tests/test_create_routes.py index 974e996a..dd8e2d8b 100644 --- a/tests/test_create_routes.py +++ b/tests/test_create_routes.py @@ -1,7 +1,6 @@ # Standard library imports import os import uuid -from typing import Any, Callable, Dict, List # Third party imports import pytest @@ -12,12 +11,12 @@ @pytest.fixture -def point_data() -> Dict[str, Any]: +def point_data() -> test_utils.JsonData: return {"name": "test_point", "x": 1.0, "y": 2.0, "z": 3.0} @pytest.fixture -def aoi_data() -> Dict[str, Any]: +def aoi_data() -> test_utils.JsonData: return { "name": "test_aoi", "points": [ @@ -31,7 +30,7 @@ def aoi_data() -> Dict[str, Any]: @pytest.fixture -def voi_data() -> Dict[str, Any]: +def voi_data() -> test_utils.JsonData: """Fixture for Volume of Interest (VOI) test data.""" return { "name": "test_voi", @@ -42,7 +41,7 @@ def voi_data() -> Dict[str, Any]: } -def test_create_point(client: FlaskClient, point_data: Dict[str, Any]) -> None: +def test_create_point(client: FlaskClient, point_data: test_utils.JsonData) -> None: """Test the creation of a point with valid data.""" route: str = "/opengeodeweb_back/create/create_point" @@ -51,23 +50,23 @@ def test_create_point(client: FlaskClient, point_data: Dict[str, Any]) -> None: assert response.status_code == 200 # Verify response data - response_data: Any = response.json + response_data = response.get_json() assert "viewable_file_name" in response_data assert "id" in response_data assert "name" in response_data assert "native_file_name" in response_data - assert "object_type" in response_data - assert "geode_object" in response_data + assert "viewer_type" in response_data + assert "geode_object_type" in response_data assert response_data["name"] == point_data["name"] - assert response_data["object_type"] == "mesh" - assert response_data["geode_object"] == "PointSet3D" + assert response_data["viewer_type"] == "mesh" + assert response_data["geode_object_type"] == "PointSet3D" # Test with missing parameters - test_utils.test_route_wrong_params(client, route, lambda: point_data.copy()) # type: ignore + test_utils.test_route_wrong_params(client, route, lambda: point_data.copy()) -def test_create_aoi(client: FlaskClient, aoi_data: Dict[str, Any]) -> None: +def test_create_aoi(client: FlaskClient, aoi_data: test_utils.JsonData) -> None: """Test the creation of an AOI with valid data.""" route: str = "/opengeodeweb_back/create/create_aoi" @@ -76,30 +75,30 @@ def test_create_aoi(client: FlaskClient, aoi_data: Dict[str, Any]) -> None: assert response.status_code == 200 # Verify response data - response_data: Any = response.json + response_data = response.get_json() assert "viewable_file_name" in response_data assert "id" in response_data assert "name" in response_data assert "native_file_name" in response_data - assert "object_type" in response_data - assert "geode_object" in response_data + assert "viewer_type" in response_data + assert "geode_object_type" in response_data assert response_data["name"] == aoi_data["name"] - assert response_data["object_type"] == "mesh" - assert response_data["geode_object"] == "EdgedCurve3D" + assert response_data["viewer_type"] == "mesh" + assert response_data["geode_object_type"] == "EdgedCurve3D" # Test with missing parameters - test_utils.test_route_wrong_params(client, route, lambda: aoi_data.copy()) # type: ignore + test_utils.test_route_wrong_params(client, route, lambda: aoi_data.copy()) def test_create_voi( - client: FlaskClient, aoi_data: Dict[str, Any], voi_data: Dict[str, Any] + client: FlaskClient, aoi_data: test_utils.JsonData, voi_data: test_utils.JsonData ) -> None: """Test the creation of a VOI with valid data (including optional id).""" aoi_route = "/opengeodeweb_back/create/create_aoi" aoi_response = client.post(aoi_route, json=aoi_data) assert aoi_response.status_code == 200 - aoi_id = aoi_response.json["id"] + aoi_id = aoi_response.get_json()["id"] voi_data["aoi_id"] = aoi_id @@ -107,12 +106,12 @@ def test_create_voi( response = client.post(voi_route, json=voi_data) assert response.status_code == 200 - response_data = response.json + response_data = response.get_json() assert "id" in response_data assert "name" in response_data assert response_data["name"] == voi_data["name"] - assert response_data["object_type"] == "mesh" - assert response_data["geode_object"] == "EdgedCurve3D" + assert response_data["viewer_type"] == "mesh" + assert response_data["geode_object_type"] == "EdgedCurve3D" def test_create_point_with_invalid_data(client: FlaskClient) -> None: @@ -120,7 +119,7 @@ def test_create_point_with_invalid_data(client: FlaskClient) -> None: route: str = "/opengeodeweb_back/create/create_point" # Test with non-numeric coordinates - invalid_data: Dict[str, Any] = { + invalid_data: test_utils.JsonData = { "name": "invalid_point", "x": "not_a_number", "y": 2.0, @@ -136,12 +135,12 @@ def test_create_point_with_invalid_data(client: FlaskClient) -> None: def test_create_aoi_with_invalid_data( - client: FlaskClient, aoi_data: Dict[str, Any] + client: FlaskClient, aoi_data: test_utils.JsonData ) -> None: """Test the AOI creation endpoint with invalid data.""" route: str = "/opengeodeweb_back/create/create_aoi" - invalid_data: Dict[str, Any] = { + invalid_data: test_utils.JsonData = { **aoi_data, "points": [ {"x": "not_a_number", "y": 0.0}, @@ -163,13 +162,13 @@ def test_create_aoi_with_invalid_data( def test_create_voi_with_invalid_data( - client: FlaskClient, aoi_data: Dict[str, Any], voi_data: Dict[str, Any] + client: FlaskClient, aoi_data: test_utils.JsonData, voi_data: test_utils.JsonData ) -> None: """Test the VOI creation endpoint with invalid data.""" aoi_route = "/opengeodeweb_back/create/create_aoi" aoi_response = client.post(aoi_route, json=aoi_data) assert aoi_response.status_code == 200 - aoi_id = aoi_response.json["id"] + aoi_id = aoi_response.get_json()["id"] route = "/opengeodeweb_back/create/create_aoi" diff --git a/tests/test_models_routes.py b/tests/test_models_routes.py index f9841962..47f4f606 100644 --- a/tests/test_models_routes.py +++ b/tests/test_models_routes.py @@ -183,11 +183,5 @@ def test_save_viewable_workflow_from_object(client: FlaskClient) -> None: data_id = response.get_json()["id"] assert isinstance(data_id, str) and len(data_id) > 0 - assert response.get_json()["geode_object"] == "EdgedCurve3D" + assert response.get_json()["geode_object_type"] == "EdgedCurve3D" assert response.get_json()["viewable_file_name"].endswith(".vtp") - - attr_resp = client.post( - "/opengeodeweb_back/vertex_attribute_names", json={"id": data_id} - ) - assert attr_resp.status_code == 200 - assert isinstance(attr_resp.get_json().get("vertex_attribute_names", []), list) diff --git a/tests/test_routes.py b/tests/test_routes.py index c18410b6..9625657c 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -9,6 +9,12 @@ from opengeodeweb_microservice.database.data import Data from opengeodeweb_microservice.database.connection import get_session from opengeodeweb_back import geode_functions, test_utils +from opengeodeweb_back.geode_objects.geode_polygonal_surface3d import ( + GeodePolygonalSurface3D, +) +from opengeodeweb_back.geode_objects.geode_polyhedral_solid3d import ( + GeodePolyhedralSolid3D, +) base_dir = os.path.abspath(os.path.dirname(__file__)) data_dir = os.path.join(base_dir, "data") @@ -18,9 +24,7 @@ def test_allowed_files(client: FlaskClient) -> None: route = f"/opengeodeweb_back/allowed_files" def get_full_data() -> test_utils.JsonData: - return { - "filename": "corbi.og_brep", - } + return {} json = get_full_data() response = client.post(route, json=json) @@ -146,8 +150,7 @@ def get_full_data() -> test_utils.JsonData: for geode_object, values in geode_objects_and_output_extensions.items(): assert type(values) is dict for output_extension, value in values.items(): - assert type(value) is dict - assert type(value["is_saveable"]) is bool + assert type(value) is bool # Test all params test_utils.test_route_wrong_params(client, route, get_full_data) @@ -172,7 +175,7 @@ def get_full_data() -> test_utils.JsonData: assert type(viewable_file_name) is str id = response.get_json().get("id") assert type(id) is str - object_type = response.get_json()["object_type"] + object_type = response.get_json()["viewer_type"] assert type(object_type) is str assert object_type in ["model", "mesh"] binary_light_viewable = response.get_json()["binary_light_viewable"] @@ -186,8 +189,8 @@ def test_texture_coordinates(client: FlaskClient, test_id: str) -> None: with client.application.app_context(): file = os.path.join(data_dir, "hat.vtp") data = Data.create( - geode_object="PolygonalSurface3D", - viewer_object=geode_functions.get_object_type("PolygonalSurface3D"), + geode_object=GeodePolygonalSurface3D.geode_object_type(), + viewer_object=GeodePolygonalSurface3D.viewer_type(), input_file=file, ) data.native_file_name = file @@ -214,8 +217,8 @@ def test_vertex_attribute_names(client: FlaskClient, test_id: str) -> None: with client.application.app_context(): file = os.path.join(data_dir, "test.vtp") data = Data.create( - geode_object="PolygonalSurface3D", - viewer_object=geode_functions.get_object_type("PolygonalSurface3D"), + geode_object=GeodePolygonalSurface3D.geode_object_type(), + viewer_object=GeodePolygonalSurface3D.viewer_type(), input_file=file, ) data.native_file_name = file @@ -240,8 +243,8 @@ def test_polygon_attribute_names(client: FlaskClient, test_id: str) -> None: with client.application.app_context(): file = os.path.join(data_dir, "test.vtp") data = Data.create( - geode_object="PolygonalSurface3D", - viewer_object=geode_functions.get_object_type("PolygonalSurface3D"), + geode_object=GeodePolygonalSurface3D.geode_object_type(), + viewer_object=GeodePolygonalSurface3D.viewer_type(), input_file=file, ) data.native_file_name = file @@ -266,8 +269,8 @@ def test_polyhedron_attribute_names(client: FlaskClient, test_id: str) -> None: with client.application.app_context(): file = os.path.join(data_dir, "test.vtu") data = Data.create( - geode_object="PolyhedralSolid3D", - viewer_object=geode_functions.get_object_type("PolyhedralSolid3D"), + geode_object=GeodePolyhedralSolid3D.geode_object_type(), + viewer_object=GeodePolyhedralSolid3D.viewer_type(), input_file=file, ) data.native_file_name = file From 4669f566e1e85a5c6aa85da607ad1dc2bd440d3f Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Mon, 24 Nov 2025 11:15:04 +0100 Subject: [PATCH 08/21] fix --- src/opengeodeweb_back/geode_objects/geode_raster_image2d.py | 3 +++ src/opengeodeweb_back/geode_objects/geode_raster_image3d.py | 3 +++ src/opengeodeweb_back/utils_functions.py | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py b/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py index c7201df0..1cd24e52 100644 --- a/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py @@ -78,3 +78,6 @@ def save_light_viewable(self, filename_without_extension: str) -> str: def inspect(self) -> None: return None + + def vertex_attribute_manager(self) -> og.AttributeManager: + return og.AttributeManager() diff --git a/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py b/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py index a6fb8555..6aef8db7 100644 --- a/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py @@ -78,3 +78,6 @@ def save_light_viewable(self, filename_without_extension: str) -> str: def inspect(self) -> None: return None + + def vertex_attribute_manager(self) -> og.AttributeManager: + return og.AttributeManager() diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index b4e7b23e..8483936d 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -20,7 +20,8 @@ # Local application imports from . import geode_functions from .geode_objects import geode_objects -from .geode_objects.geode_object import GeodeObjectType, GeodeObject +from .geode_objects.types import GeodeObjectType +from .geode_objects.geode_object import GeodeObject def increment_request_counter(current_app: flask.Flask) -> None: From b75a456b056276b1713b90bb8d04fcfcdcbce45b Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Mon, 24 Nov 2025 14:22:43 +0100 Subject: [PATCH 09/21] fix --- src/opengeodeweb_back/geode_functions.py | 78 ------------------- .../geode_objects/geode_edged_curve2d.py | 2 +- .../geode_objects/geode_edged_curve3d.py | 2 +- src/opengeodeweb_back/geode_objects/types.py | 25 ++++-- 4 files changed, 21 insertions(+), 86 deletions(-) diff --git a/src/opengeodeweb_back/geode_functions.py b/src/opengeodeweb_back/geode_functions.py index 1a4e4590..f573bf84 100644 --- a/src/opengeodeweb_back/geode_functions.py +++ b/src/opengeodeweb_back/geode_functions.py @@ -79,81 +79,3 @@ def geode_object_output_extensions( if hasattr(mixin_geode_object, "geode_object_type"): results[mixin_geode_object.geode_object_type()] = object_output_extensions return results - - -# def assign_crs(geode_object_type: GeodeObjectType, data, crs_name: str, info): -# builder = create_builder(geode_object, data) -# geode_objects[geode_object_type].["crs"]["assign"](data, builder, crs_name, info) - - -# def convert_crs(geode_object_type: GeodeObjectType, data, crs_name: str, info): -# builder = create_builder(geode_object, data) -# geode_objects[geode_object_type].["crs"]["convert"](data, builder, crs_name, info) - - -# def create_crs( -# geode_object_type: GeodeObjectType, -# data, -# name: str, -# input_coordiante_system, -# output_coordiante_system, -# ): -# builder = create_builder(geode_object, data) -# geode_objects[geode_object_type].["crs"]["create"]( -# data, builder, name, input_coordiante_system, output_coordiante_system -# ) - - -# def geographic_coordinate_systems_info(geode_object_type: GeodeObjectType, crs): -# if is_3D(geode_object): -# return og_gs.GeographicCoordinateSystemInfo3D( -# crs["authority"], crs["code"], crs["name"] -# ) -# else: -# return og_gs.GeographicCoordinateSystemInfo2D( -# crs["authority"], crs["code"], crs["name"] -# ) - - -# def coordinate_system(geode_object_type: GeodeObjectType, coordinate_system): -# return og.CoordinateSystem2D( -# [ -# og.Vector2D( -# og.Point2D( -# [coordinate_system["origin_x"], coordinate_system["origin_y"]] -# ), -# og.Point2D( -# [coordinate_system["point_1_x"], coordinate_system["point_1_y"]] -# ), -# ), -# og.Vector2D( -# og.Point2D( -# [coordinate_system["origin_x"], coordinate_system["origin_y"]] -# ), -# og.Point2D( -# [coordinate_system["point_2_x"], coordinate_system["point_2_y"]] -# ), -# ), -# ], -# og.Point2D([coordinate_system["origin_x"], coordinate_system["origin_y"]]), -# ) - - -# def assign_geographic_coordinate_system_info(geode_object_type: GeodeObjectType, data, input_crs): -# info = geographic_coordinate_systems_info(geode_object, input_crs) -# assign_crs(geode_object, data, input_crs["name"], info) - - -# def convert_geographic_coordinate_system_info(geode_object_type: GeodeObjectType, data, output_crs): -# info = geographic_coordinate_systems_info(geode_object, output_crs) -# convert_crs(geode_object, data, output_crs["name"], info) - - -# def create_coordinate_system( -# geode_object_type: GeodeObjectType, data, name, input_coordinate_points, output_coordinate_points -# ): -# input_coordiante_system = coordinate_system(geode_object, input_coordinate_points) -# output_coordiante_system = coordinate_system(geode_object, output_coordinate_points) -# create_crs( -# geode_object, data, name, input_coordiante_system, output_coordiante_system -# ) diff --git a/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py b/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py index bcb4e8d8..a0124882 100644 --- a/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py @@ -34,7 +34,7 @@ def is_3D(cls) -> bool: @classmethod def is_viewable(cls) -> bool: - return False + return True def builder(self) -> og.EdgedCurveBuilder2D: return og.EdgedCurveBuilder2D.create(self.edged_curve) diff --git a/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py b/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py index 0f35a212..632da9a7 100644 --- a/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py @@ -34,7 +34,7 @@ def is_3D(cls) -> bool: @classmethod def is_viewable(cls) -> bool: - return False + return True def builder(self) -> og.EdgedCurveBuilder3D: return og.EdgedCurveBuilder3D.create(self.edged_curve) diff --git a/src/opengeodeweb_back/geode_objects/types.py b/src/opengeodeweb_back/geode_objects/types.py index f42fed08..57fbccf6 100644 --- a/src/opengeodeweb_back/geode_objects/types.py +++ b/src/opengeodeweb_back/geode_objects/types.py @@ -5,28 +5,41 @@ # Local application imports - -GeodeMeshType = Literal[ - "VertexSet", - "Graph", +GeodePointMeshType = Literal[ "PointSet2D", "PointSet3D", +] +GeodeEdgeMeshType = Literal[ "EdgedCurve2D", "EdgedCurve3D", +] +GeodePolygonMeshType = Literal[ "RasterImage2D", - "RasterImage3D", "PolygonalSurface2D", "PolygonalSurface3D", "TriangulatedSurface2D", "TriangulatedSurface3D", "RegularGrid2D", + "LightRegularGrid2D", +] +GeodePolyhedronMeshType = Literal[ + "RasterImage3D", "PolyhedralSolid3D", "TetrahedralSolid3D", "HybridSolid3D", "RegularGrid3D", - "LightRegularGrid2D", "LightRegularGrid3D", ] +GeodeMeshType = ( + Literal[ + "VertexSet", + "Graph", + ] + | GeodePointMeshType + | GeodeEdgeMeshType + | GeodePolygonMeshType + | GeodePolyhedronMeshType +) GeodeModelType = Literal[ "BRep", "Section", From 496f7ff7fea355bc02db5af4af0f488f8944cd39 Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Thu, 27 Nov 2025 12:33:04 +0100 Subject: [PATCH 10/21] refactor json_data, tests okay --- requirements.txt | 50 +++++++++++++++---- src/opengeodeweb_back/app.py | 12 +++-- .../routes/blueprint_routes.py | 45 ++++++++--------- .../routes/create/blueprint_create.py | 8 +-- .../routes/models/blueprint_models.py | 8 +-- src/opengeodeweb_back/utils_functions.py | 5 +- 6 files changed, 83 insertions(+), 45 deletions(-) diff --git a/requirements.txt b/requirements.txt index 08d64bdf..16a7afd1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,15 +2,19 @@ # This file is autogenerated by pip-compile with Python 3.12 # by the following command: # -# pip-compile --output-file=./requirements.txt ./requirements.in +# pip-compile --output-file=./requirements.txt ./requirements-internal.in ./requirements.in # -asgiref>=3 +asgiref==3.11.0 # via flask -blinker>=1 +blinker==1.9.0 # via flask -click>=8 +click==8.3.1 # via flask -flask[async]>=3 +dataclasses-json==0.6.7 + # via opengeodeweb-microservice +fastjsonschema==2.21.1 + # via opengeodeweb-microservice +flask[async]==3.1.2 # via # -r requirements.in # flask-cors @@ -22,15 +26,27 @@ geode-common==33.11.3 # geode-viewables geode-viewables==3.3.2 # via -r requirements.in -itsdangerous>=2 +greenlet==3.2.4 + # via + # opengeodeweb-microservice + # sqlalchemy +itsdangerous==2.2.0 # via flask -jinja2>=3 +jinja2==3.1.6 # via flask -markupsafe>=3 +markupsafe==3.0.3 # via # flask # jinja2 # werkzeug +marshmallow==3.26.1 + # via + # dataclasses-json + # opengeodeweb-microservice +mypy-extensions==1.1.0 + # via + # opengeodeweb-microservice + # typing-inspect opengeode-core==15.30.4 # via # -r requirements.in @@ -54,9 +70,25 @@ opengeode-io==7.4.6 # -r requirements.in # geode-viewables # opengeode-geosciencesio +opengeodeweb-microservice==1.0.9 + # via -r requirements-internal.in +packaging==25.0 + # via + # marshmallow + # opengeodeweb-microservice +sqlalchemy==2.0.44 + # via opengeodeweb-microservice +typing-extensions==4.15.0 + # via + # opengeodeweb-microservice + # sqlalchemy + # typing-inspect +typing-inspect==0.9.0 + # via + # dataclasses-json + # opengeodeweb-microservice werkzeug==3.1.2 # via # -r requirements.in # flask # flask-cors - diff --git a/src/opengeodeweb_back/app.py b/src/opengeodeweb_back/app.py index 1202ecb1..3496c93e 100644 --- a/src/opengeodeweb_back/app.py +++ b/src/opengeodeweb_back/app.py @@ -2,7 +2,6 @@ import argparse import os -import time from typing import Any import flask import flask_cors # type: ignore @@ -36,8 +35,13 @@ @app.before_request -def before_request() -> None: +def before_request() -> flask.Response|None: + if flask.request.method == "OPTIONS": + response = flask.make_response() + response.headers['Access-Control-Allow-Methods'] = 'GET,POST,PUT,DELETE,OPTIONS' + return response utils_functions.before_request(flask.current_app) + return None @app.teardown_request @@ -111,7 +115,7 @@ def run_server() -> None: parser.add_argument( "-d", "--debug", - default=FLASK_DEBUG, + default=True, help="Whether to run in debug mode", action="store_true", ) @@ -145,7 +149,7 @@ def run_server() -> None: app.config.update(DATA_FOLDER_PATH=args.data_folder_path) app.config.update(UPLOAD_FOLDER=args.upload_folder_path) app.config.update(MINUTES_BEFORE_TIMEOUT=args.timeout) - flask_cors.CORS(app, origins=args.allowed_origins) + flask_cors.CORS(app, origins=args.allowed_origins, methods=["GET", "POST", "PUT"]) print( f"Host: {args.host}, Port: {args.port}, Debug: {args.debug}, " f"Data folder path: {args.data_folder_path}, Timeout: {args.timeout}, " diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index b8930ed0..997d6de9 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -43,7 +43,6 @@ ) def allowed_files() -> flask.Response: utils_functions.validate_request(flask.request, schemas_dict["allowed_files"]) - params = schemas.AllowedFiles.from_dict(flask.request.get_json()) extensions: set[str] = set() for geode_object in geode_objects.values(): for extension in geode_object.input_extensions(): @@ -71,8 +70,8 @@ def upload_file() -> flask.Response: methods=schemas_dict["allowed_objects"]["methods"], ) def allowed_objects() -> flask.Response: - utils_functions.validate_request(flask.request, schemas_dict["allowed_objects"]) - params = schemas.AllowedObjects.from_dict(flask.request.get_json()) + json_data = utils_functions.validate_request(flask.request, schemas_dict["allowed_objects"]) + params = schemas.AllowedObjects.from_dict(json_data) file_absolute_path = geode_functions.upload_file_path(params.filename) file_extension = utils_functions.extension_from_filename( os.path.basename(file_absolute_path) @@ -95,8 +94,8 @@ def allowed_objects() -> flask.Response: methods=schemas_dict["missing_files"]["methods"], ) def missing_files() -> flask.Response: - utils_functions.validate_request(flask.request, schemas_dict["missing_files"]) - params = schemas.MissingFiles.from_dict(flask.request.get_json()) + json_data = utils_functions.validate_request(flask.request, schemas_dict["missing_files"]) + params = schemas.MissingFiles.from_dict(json_data) file_path = geode_functions.upload_file_path(params.filename) geode_object = geode_functions.geode_object_from_string(params.geode_object_type) additional_files = geode_object.additional_files( @@ -132,10 +131,10 @@ def missing_files() -> flask.Response: methods=schemas_dict["geographic_coordinate_systems"]["methods"], ) def crs_converter_geographic_coordinate_systems() -> flask.Response: - utils_functions.validate_request( + json_data = utils_functions.validate_request( flask.request, schemas_dict["geographic_coordinate_systems"] ) - params = schemas.GeographicCoordinateSystems.from_dict(flask.request.get_json()) + params = schemas.GeographicCoordinateSystems.from_dict(json_data) geode_object = geode_functions.geode_object_from_string(params.geode_object_type) infos = ( og_geosciences.GeographicCoordinateSystem3D.geographic_coordinate_systems() @@ -157,8 +156,8 @@ def crs_converter_geographic_coordinate_systems() -> flask.Response: methods=schemas_dict["inspect_file"]["methods"], ) def inspect_file() -> flask.Response: - utils_functions.validate_request(flask.request, schemas_dict["inspect_file"]) - params = schemas.InspectFile.from_dict(flask.request.get_json()) + json_data = utils_functions.validate_request(flask.request, schemas_dict["inspect_file"]) + params = schemas.InspectFile.from_dict(json_data) file_path = geode_functions.upload_file_path(params.filename) geode_object = geode_functions.geode_object_from_string( params.geode_object_type @@ -201,10 +200,10 @@ def extract_inspector_result(inspection_data: Any) -> object: methods=schemas_dict["geode_objects_and_output_extensions"]["methods"], ) def geode_objects_and_output_extensions() -> flask.Response: - utils_functions.validate_request( + json_data = utils_functions.validate_request( flask.request, schemas_dict["geode_objects_and_output_extensions"] ) - params = schemas.GeodeObjectsAndOutputExtensions.from_dict(flask.request.get_json()) + params = schemas.GeodeObjectsAndOutputExtensions.from_dict(json_data) file_path = geode_functions.upload_file_path(params.filename) geode_object = geode_functions.geode_object_from_string( params.geode_object_type @@ -223,8 +222,8 @@ def geode_objects_and_output_extensions() -> flask.Response: methods=schemas_dict["save_viewable_file"]["methods"], ) def save_viewable_file() -> flask.Response: - utils_functions.validate_request(flask.request, schemas_dict["save_viewable_file"]) - params = schemas.SaveViewableFile.from_dict(flask.request.get_json()) + json_data = utils_functions.validate_request(flask.request, schemas_dict["save_viewable_file"]) + params = schemas.SaveViewableFile.from_dict(json_data) return flask.make_response( utils_functions.generate_native_viewable_and_light_viewable_from_file( geode_object_type=geode_object_type(params.geode_object_type), @@ -239,8 +238,8 @@ def save_viewable_file() -> flask.Response: methods=schemas_dict["texture_coordinates"]["methods"], ) def texture_coordinates() -> flask.Response: - utils_functions.validate_request(flask.request, schemas_dict["texture_coordinates"]) - params = schemas.TextureCoordinates.from_dict(flask.request.get_json()) + json_data = utils_functions.validate_request(flask.request, schemas_dict["texture_coordinates"]) + params = schemas.TextureCoordinates.from_dict(json_data) geode_object = geode_functions.load_geode_object(params.id) if not isinstance(geode_object, GeodeSurfaceMesh2D | GeodeSurfaceMesh3D): flask.abort(500, f"{params.id} is not a GeodeSurfaceMesh") @@ -253,10 +252,10 @@ def texture_coordinates() -> flask.Response: methods=schemas_dict["vertex_attribute_names"]["methods"], ) def vertex_attribute_names() -> flask.Response: - utils_functions.validate_request( + json_data = utils_functions.validate_request( flask.request, schemas_dict["vertex_attribute_names"] ) - params = schemas.VertexAttributeNames.from_dict(flask.request.get_json()) + params = schemas.VertexAttributeNames.from_dict(json_data) geode_object = geode_functions.load_geode_object(params.id) if not isinstance(geode_object, GeodeMesh): flask.abort(500, f"{params.id} is not a GeodeMesh") @@ -274,10 +273,10 @@ def vertex_attribute_names() -> flask.Response: methods=schemas_dict["polygon_attribute_names"]["methods"], ) def polygon_attribute_names() -> flask.Response: - utils_functions.validate_request( + json_data = utils_functions.validate_request( flask.request, schemas_dict["polygon_attribute_names"] ) - params = schemas.PolygonAttributeNames.from_dict(flask.request.get_json()) + params = schemas.PolygonAttributeNames.from_dict(json_data) geode_object = geode_functions.load_geode_object(params.id) if not isinstance(geode_object, GeodeSurfaceMesh2D | GeodeSurfaceMesh3D): flask.abort(500, f"{params.id} is not a GeodeSurfaceMesh") @@ -295,10 +294,10 @@ def polygon_attribute_names() -> flask.Response: methods=schemas_dict["polyhedron_attribute_names"]["methods"], ) def polyhedron_attribute_names() -> flask.Response: - utils_functions.validate_request( + json_data = utils_functions.validate_request( flask.request, schemas_dict["polyhedron_attribute_names"] ) - params = schemas.PolyhedronAttributeNames.from_dict(flask.request.get_json()) + params = schemas.PolyhedronAttributeNames.from_dict(json_data) geode_object = geode_functions.load_geode_object(params.id) if not isinstance(geode_object, GeodeSolidMesh3D): flask.abort(500, f"{params.id} is not a GeodeSolidMesh") @@ -335,8 +334,8 @@ def kill() -> flask.Response: methods=schemas_dict["export_project"]["methods"], ) def export_project() -> flask.Response: - utils_functions.validate_request(flask.request, schemas_dict["export_project"]) - params = schemas.ExportProject.from_dict(flask.request.get_json()) + json_data = utils_functions.validate_request(flask.request, schemas_dict["export_project"]) + params = schemas.ExportProject.from_dict(json_data) project_folder: str = flask.current_app.config["DATA_FOLDER_PATH"] os.makedirs(project_folder, exist_ok=True) diff --git a/src/opengeodeweb_back/routes/create/blueprint_create.py b/src/opengeodeweb_back/routes/create/blueprint_create.py index b9ad3b03..07215270 100644 --- a/src/opengeodeweb_back/routes/create/blueprint_create.py +++ b/src/opengeodeweb_back/routes/create/blueprint_create.py @@ -22,8 +22,8 @@ ) def create_point() -> flask.Response: """Endpoint to create a single point in 3D space.""" - utils_functions.validate_request(flask.request, schemas_dict["create_point"]) - params = schemas.CreatePoint.from_dict(flask.request.get_json()) + json_data = utils_functions.validate_request(flask.request, schemas_dict["create_point"]) + params = schemas.CreatePoint.from_dict(json_data) # Create the point pointset = GeodePointSet3D() @@ -43,8 +43,8 @@ def create_point() -> flask.Response: ) def create_aoi() -> flask.Response: """Endpoint to create an Area of Interest (AOI) as an EdgedCurve3D.""" - utils_functions.validate_request(flask.request, schemas_dict["create_aoi"]) - params = schemas.CreateAoi.from_dict(flask.request.get_json()) + json_data = utils_functions.validate_request(flask.request, schemas_dict["create_aoi"]) + params = schemas.CreateAoi.from_dict(json_data) # Create the edged curve edged_curve = GeodeEdgedCurve3D() diff --git a/src/opengeodeweb_back/routes/models/blueprint_models.py b/src/opengeodeweb_back/routes/models/blueprint_models.py index 2b3ff7f5..a55fca36 100644 --- a/src/opengeodeweb_back/routes/models/blueprint_models.py +++ b/src/opengeodeweb_back/routes/models/blueprint_models.py @@ -16,10 +16,10 @@ methods=schemas_dict["vtm_component_indices"]["methods"], ) def uuid_to_flat_index() -> flask.Response: - utils_functions.validate_request( + json_data = utils_functions.validate_request( flask.request, schemas_dict["vtm_component_indices"] ) - params = schemas.VtmComponentIndices.from_dict(flask.request.get_json()) + params = schemas.VtmComponentIndices.from_dict(json_data) vtm_file_path = geode_functions.data_file_path(params.id, "viewable.vtm") tree = ET.parse(vtm_file_path) root = tree.find("vtkMultiBlockDataSet") @@ -39,8 +39,8 @@ def uuid_to_flat_index() -> flask.Response: methods=schemas_dict["mesh_components"]["methods"], ) def extract_uuids_endpoint() -> flask.Response: - utils_functions.validate_request(flask.request, schemas_dict["mesh_components"]) - params = schemas.MeshComponents.from_dict(flask.request.get_json()) + json_data = utils_functions.validate_request(flask.request, schemas_dict["mesh_components"]) + params = schemas.MeshComponents.from_dict(json_data) model = geode_functions.load_geode_object(params.id) if not isinstance(model, GeodeModel): flask.abort(500, f"{params.id} is not a GeodeModel") diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index 8483936d..ad516c52 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -1,4 +1,5 @@ # Standard library imports +import json import os import threading import time @@ -101,7 +102,7 @@ def versions(list_packages: list[str]) -> list[dict[str, str]]: return list_with_versions -def validate_request(request: flask.Request, schema: SchemaDict) -> None: +def validate_request(request: flask.Request, schema: SchemaDict) -> dict: json_data = request.get_json(force=True, silent=True) if json_data is None: @@ -113,6 +114,7 @@ def validate_request(request: flask.Request, schema: SchemaDict) -> None: error_msg = str(e) print("Validation failed:", error_msg, flush=True) flask.abort(400, error_msg) + return json_data def set_interval( @@ -169,6 +171,7 @@ def handle_exception(exception: HTTPException) -> flask.Response: "description": exception.description or "An error occurred", } ) + response.content_type = "application/json" response.status_code = exception.code or 500 return response From 87c93f1ed57814134377c90594400f07e8e7ce2c Mon Sep 17 00:00:00 2001 From: JulienChampagnol <91873154+JulienChampagnol@users.noreply.github.com> Date: Thu, 27 Nov 2025 11:33:40 +0000 Subject: [PATCH 11/21] Apply prepare changes --- requirements.txt | 50 ++++--------------- src/opengeodeweb_back/app.py | 4 +- .../routes/blueprint_routes.py | 24 ++++++--- .../routes/create/blueprint_create.py | 8 ++- .../routes/models/blueprint_models.py | 4 +- 5 files changed, 38 insertions(+), 52 deletions(-) diff --git a/requirements.txt b/requirements.txt index 16a7afd1..08d64bdf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,19 +2,15 @@ # This file is autogenerated by pip-compile with Python 3.12 # by the following command: # -# pip-compile --output-file=./requirements.txt ./requirements-internal.in ./requirements.in +# pip-compile --output-file=./requirements.txt ./requirements.in # -asgiref==3.11.0 +asgiref>=3 # via flask -blinker==1.9.0 +blinker>=1 # via flask -click==8.3.1 +click>=8 # via flask -dataclasses-json==0.6.7 - # via opengeodeweb-microservice -fastjsonschema==2.21.1 - # via opengeodeweb-microservice -flask[async]==3.1.2 +flask[async]>=3 # via # -r requirements.in # flask-cors @@ -26,27 +22,15 @@ geode-common==33.11.3 # geode-viewables geode-viewables==3.3.2 # via -r requirements.in -greenlet==3.2.4 - # via - # opengeodeweb-microservice - # sqlalchemy -itsdangerous==2.2.0 +itsdangerous>=2 # via flask -jinja2==3.1.6 +jinja2>=3 # via flask -markupsafe==3.0.3 +markupsafe>=3 # via # flask # jinja2 # werkzeug -marshmallow==3.26.1 - # via - # dataclasses-json - # opengeodeweb-microservice -mypy-extensions==1.1.0 - # via - # opengeodeweb-microservice - # typing-inspect opengeode-core==15.30.4 # via # -r requirements.in @@ -70,25 +54,9 @@ opengeode-io==7.4.6 # -r requirements.in # geode-viewables # opengeode-geosciencesio -opengeodeweb-microservice==1.0.9 - # via -r requirements-internal.in -packaging==25.0 - # via - # marshmallow - # opengeodeweb-microservice -sqlalchemy==2.0.44 - # via opengeodeweb-microservice -typing-extensions==4.15.0 - # via - # opengeodeweb-microservice - # sqlalchemy - # typing-inspect -typing-inspect==0.9.0 - # via - # dataclasses-json - # opengeodeweb-microservice werkzeug==3.1.2 # via # -r requirements.in # flask # flask-cors + diff --git a/src/opengeodeweb_back/app.py b/src/opengeodeweb_back/app.py index 3496c93e..78fba0a4 100644 --- a/src/opengeodeweb_back/app.py +++ b/src/opengeodeweb_back/app.py @@ -35,10 +35,10 @@ @app.before_request -def before_request() -> flask.Response|None: +def before_request() -> flask.Response | None: if flask.request.method == "OPTIONS": response = flask.make_response() - response.headers['Access-Control-Allow-Methods'] = 'GET,POST,PUT,DELETE,OPTIONS' + response.headers["Access-Control-Allow-Methods"] = "GET,POST,PUT,DELETE,OPTIONS" return response utils_functions.before_request(flask.current_app) return None diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index 997d6de9..f5489a1c 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -70,7 +70,9 @@ def upload_file() -> flask.Response: methods=schemas_dict["allowed_objects"]["methods"], ) def allowed_objects() -> flask.Response: - json_data = utils_functions.validate_request(flask.request, schemas_dict["allowed_objects"]) + json_data = utils_functions.validate_request( + flask.request, schemas_dict["allowed_objects"] + ) params = schemas.AllowedObjects.from_dict(json_data) file_absolute_path = geode_functions.upload_file_path(params.filename) file_extension = utils_functions.extension_from_filename( @@ -94,7 +96,9 @@ def allowed_objects() -> flask.Response: methods=schemas_dict["missing_files"]["methods"], ) def missing_files() -> flask.Response: - json_data = utils_functions.validate_request(flask.request, schemas_dict["missing_files"]) + json_data = utils_functions.validate_request( + flask.request, schemas_dict["missing_files"] + ) params = schemas.MissingFiles.from_dict(json_data) file_path = geode_functions.upload_file_path(params.filename) geode_object = geode_functions.geode_object_from_string(params.geode_object_type) @@ -156,7 +160,9 @@ def crs_converter_geographic_coordinate_systems() -> flask.Response: methods=schemas_dict["inspect_file"]["methods"], ) def inspect_file() -> flask.Response: - json_data = utils_functions.validate_request(flask.request, schemas_dict["inspect_file"]) + json_data = utils_functions.validate_request( + flask.request, schemas_dict["inspect_file"] + ) params = schemas.InspectFile.from_dict(json_data) file_path = geode_functions.upload_file_path(params.filename) geode_object = geode_functions.geode_object_from_string( @@ -222,7 +228,9 @@ def geode_objects_and_output_extensions() -> flask.Response: methods=schemas_dict["save_viewable_file"]["methods"], ) def save_viewable_file() -> flask.Response: - json_data = utils_functions.validate_request(flask.request, schemas_dict["save_viewable_file"]) + json_data = utils_functions.validate_request( + flask.request, schemas_dict["save_viewable_file"] + ) params = schemas.SaveViewableFile.from_dict(json_data) return flask.make_response( utils_functions.generate_native_viewable_and_light_viewable_from_file( @@ -238,7 +246,9 @@ def save_viewable_file() -> flask.Response: methods=schemas_dict["texture_coordinates"]["methods"], ) def texture_coordinates() -> flask.Response: - json_data = utils_functions.validate_request(flask.request, schemas_dict["texture_coordinates"]) + json_data = utils_functions.validate_request( + flask.request, schemas_dict["texture_coordinates"] + ) params = schemas.TextureCoordinates.from_dict(json_data) geode_object = geode_functions.load_geode_object(params.id) if not isinstance(geode_object, GeodeSurfaceMesh2D | GeodeSurfaceMesh3D): @@ -334,7 +344,9 @@ def kill() -> flask.Response: methods=schemas_dict["export_project"]["methods"], ) def export_project() -> flask.Response: - json_data = utils_functions.validate_request(flask.request, schemas_dict["export_project"]) + json_data = utils_functions.validate_request( + flask.request, schemas_dict["export_project"] + ) params = schemas.ExportProject.from_dict(json_data) project_folder: str = flask.current_app.config["DATA_FOLDER_PATH"] diff --git a/src/opengeodeweb_back/routes/create/blueprint_create.py b/src/opengeodeweb_back/routes/create/blueprint_create.py index 07215270..04e7448a 100644 --- a/src/opengeodeweb_back/routes/create/blueprint_create.py +++ b/src/opengeodeweb_back/routes/create/blueprint_create.py @@ -22,7 +22,9 @@ ) def create_point() -> flask.Response: """Endpoint to create a single point in 3D space.""" - json_data = utils_functions.validate_request(flask.request, schemas_dict["create_point"]) + json_data = utils_functions.validate_request( + flask.request, schemas_dict["create_point"] + ) params = schemas.CreatePoint.from_dict(json_data) # Create the point @@ -43,7 +45,9 @@ def create_point() -> flask.Response: ) def create_aoi() -> flask.Response: """Endpoint to create an Area of Interest (AOI) as an EdgedCurve3D.""" - json_data = utils_functions.validate_request(flask.request, schemas_dict["create_aoi"]) + json_data = utils_functions.validate_request( + flask.request, schemas_dict["create_aoi"] + ) params = schemas.CreateAoi.from_dict(json_data) # Create the edged curve diff --git a/src/opengeodeweb_back/routes/models/blueprint_models.py b/src/opengeodeweb_back/routes/models/blueprint_models.py index a55fca36..4ad53586 100644 --- a/src/opengeodeweb_back/routes/models/blueprint_models.py +++ b/src/opengeodeweb_back/routes/models/blueprint_models.py @@ -39,7 +39,9 @@ def uuid_to_flat_index() -> flask.Response: methods=schemas_dict["mesh_components"]["methods"], ) def extract_uuids_endpoint() -> flask.Response: - json_data = utils_functions.validate_request(flask.request, schemas_dict["mesh_components"]) + json_data = utils_functions.validate_request( + flask.request, schemas_dict["mesh_components"] + ) params = schemas.MeshComponents.from_dict(json_data) model = geode_functions.load_geode_object(params.id) if not isinstance(model, GeodeModel): From 59197465eed704ac691457a7e4601f6523a4a5c1 Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Thu, 27 Nov 2025 18:13:28 +0100 Subject: [PATCH 12/21] wip cells atributes --- opengeodeweb_back_schemas.json | 18 ++++++++++++++++ .../geode_objects/geode_grid2d.py | 5 +++++ .../geode_objects/geode_grid3d.py | 4 ++++ .../geode_light_regular_grid2d.py | 3 +++ .../geode_light_regular_grid3d.py | 3 +++ .../geode_objects/geode_regulard_grid2d.py | 1 + .../routes/blueprint_routes.py | 21 +++++++++++++++++++ .../routes/schemas/__init__.py | 1 + .../routes/schemas/cell_attribute_names.json | 13 ++++++++++++ .../routes/schemas/cell_attribute_names.py | 10 +++++++++ 10 files changed, 79 insertions(+) create mode 100644 src/opengeodeweb_back/routes/schemas/cell_attribute_names.json create mode 100644 src/opengeodeweb_back/routes/schemas/cell_attribute_names.py diff --git a/opengeodeweb_back_schemas.json b/opengeodeweb_back_schemas.json index 81e4505e..939f3206 100644 --- a/opengeodeweb_back_schemas.json +++ b/opengeodeweb_back_schemas.json @@ -406,6 +406,24 @@ ], "additionalProperties": false }, + "cell_attribute_names": { + "$id": "opengeodeweb_back/cell_attribute_names", + "route": "/cell_attribute_names", + "methods": [ + "POST" + ], + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id" + ], + "additionalProperties": false + }, "allowed_objects": { "$id": "opengeodeweb_back/allowed_objects", "route": "/allowed_objects", diff --git a/src/opengeodeweb_back/geode_objects/geode_grid2d.py b/src/opengeodeweb_back/geode_objects/geode_grid2d.py index c7b6d4d2..bf1c166c 100644 --- a/src/opengeodeweb_back/geode_objects/geode_grid2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_grid2d.py @@ -1,5 +1,6 @@ # Standard library imports from __future__ import annotations +from abc import abstractmethod # Third party imports import opengeode as og @@ -24,3 +25,7 @@ def builder(self) -> None: def inspect(self) -> None: return None + + @abstractmethod + def cell_attribute_manager(self) -> og.AttributeManager: ... + \ No newline at end of file diff --git a/src/opengeodeweb_back/geode_objects/geode_grid3d.py b/src/opengeodeweb_back/geode_objects/geode_grid3d.py index 9f8c6730..0519f6f0 100644 --- a/src/opengeodeweb_back/geode_objects/geode_grid3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_grid3d.py @@ -1,5 +1,6 @@ # Standard library imports from __future__ import annotations +from abc import abstractmethod # Third party imports import opengeode as og @@ -24,3 +25,6 @@ def builder(self) -> None: def inspect(self) -> None: return None + + @abstractmethod + def cell_attribute_manager(self) -> og.AttributeManager: ... diff --git a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py index 9ab855d1..a20baeb3 100644 --- a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py @@ -67,3 +67,6 @@ def save_light_viewable(self, filename_without_extension: str) -> str: def vertex_attribute_manager(self) -> og.AttributeManager: return self.light_regular_grid.grid_vertex_attribute_manager() + + def cell_attribute_manager(self) -> og.AttributeManager: + return self.light_regular_grid.cell_attribute_manager() diff --git a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py index 0f6b52b9..2591c338 100644 --- a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py @@ -67,3 +67,6 @@ def save_light_viewable(self, filename_without_extension: str) -> str: def vertex_attribute_manager(self) -> og.AttributeManager: return self.light_regular_grid.grid_vertex_attribute_manager() + + def cell_attribute_manager(self) -> og.AttributeManager: + return self.light_regular_grid.cell_attribute_manager() diff --git a/src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py b/src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py index e16c093c..f33fbfa7 100644 --- a/src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py @@ -9,6 +9,7 @@ # Local application imports from .types import GeodeMeshType from .geode_surface_mesh2d import GeodeSurfaceMesh2D +from .geode_grid2d import GeodeGrid2D class GeodeRegularGrid2D(GeodeSurfaceMesh2D): diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index 997d6de9..760110fd 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -21,6 +21,8 @@ from opengeodeweb_back.geode_objects import geode_objects from opengeodeweb_back.geode_objects.types import geode_object_type from opengeodeweb_back.geode_objects.geode_mesh import GeodeMesh +from opengeodeweb_back.geode_objects.geode_grid2d import GeodeGrid2D +from opengeodeweb_back.geode_objects.geode_grid3d import GeodeGrid3D from opengeodeweb_back.geode_objects.geode_surface_mesh2d import GeodeSurfaceMesh2D from opengeodeweb_back.geode_objects.geode_surface_mesh3d import GeodeSurfaceMesh3D from opengeodeweb_back.geode_objects.geode_solid_mesh3d import GeodeSolidMesh3D @@ -267,6 +269,25 @@ def vertex_attribute_names() -> flask.Response: 200, ) +@routes.route( + schemas_dict["cell_attribute_names"]["route"], + methods=schemas_dict["cell_attribute_names"]["methods"], +) +def cell_attribute_names() -> flask.Response: + json_data = utils_functions.validate_request( + flask.request, schemas_dict["cell_attribute_names"] + ) + params = schemas.PolygonAttributeNames.from_dict(json_data) + geode_object = geode_functions.load_geode_object(params.id) + if not isinstance(geode_object, GeodeGrid2D | GeodeGrid3D): + flask.abort(500, f"{params.id} is not a GeodeGrid") + cell_attribute_names = geode_object.cell_attribute_manager().attribute_names() + return flask.make_response( + { + "cell_attribute_names": cell_attribute_names, + }, + 200, + ) @routes.route( schemas_dict["polygon_attribute_names"]["route"], diff --git a/src/opengeodeweb_back/routes/schemas/__init__.py b/src/opengeodeweb_back/routes/schemas/__init__.py index 339f8961..4ad76b82 100644 --- a/src/opengeodeweb_back/routes/schemas/__init__.py +++ b/src/opengeodeweb_back/routes/schemas/__init__.py @@ -12,5 +12,6 @@ from .geographic_coordinate_systems import * from .geode_objects_and_output_extensions import * from .export_project import * +from .cell_attribute_names import * from .allowed_objects import * from .allowed_files import * diff --git a/src/opengeodeweb_back/routes/schemas/cell_attribute_names.json b/src/opengeodeweb_back/routes/schemas/cell_attribute_names.json new file mode 100644 index 00000000..0fe6632b --- /dev/null +++ b/src/opengeodeweb_back/routes/schemas/cell_attribute_names.json @@ -0,0 +1,13 @@ +{ + "route": "/cell_attribute_names", + "methods": ["POST"], + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + } + }, + "required": ["id"], + "additionalProperties": false +} diff --git a/src/opengeodeweb_back/routes/schemas/cell_attribute_names.py b/src/opengeodeweb_back/routes/schemas/cell_attribute_names.py new file mode 100644 index 00000000..df5a9996 --- /dev/null +++ b/src/opengeodeweb_back/routes/schemas/cell_attribute_names.py @@ -0,0 +1,10 @@ +from dataclasses_json import DataClassJsonMixin +from dataclasses import dataclass + + +@dataclass +class CellAttributeNames(DataClassJsonMixin): + def __post_init__(self) -> None: + print(self, flush=True) + + id: str From efaf19bd9f98f3e7cfc3ee4c5208779e99e9c062 Mon Sep 17 00:00:00 2001 From: JulienChampagnol <91873154+JulienChampagnol@users.noreply.github.com> Date: Thu, 27 Nov 2025 17:14:01 +0000 Subject: [PATCH 13/21] Apply prepare changes --- src/opengeodeweb_back/geode_objects/geode_grid2d.py | 3 +-- src/opengeodeweb_back/geode_objects/geode_grid3d.py | 2 +- .../geode_objects/geode_light_regular_grid2d.py | 2 +- .../geode_objects/geode_light_regular_grid3d.py | 2 +- src/opengeodeweb_back/routes/blueprint_routes.py | 2 ++ 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/opengeodeweb_back/geode_objects/geode_grid2d.py b/src/opengeodeweb_back/geode_objects/geode_grid2d.py index bf1c166c..dee2530b 100644 --- a/src/opengeodeweb_back/geode_objects/geode_grid2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_grid2d.py @@ -25,7 +25,6 @@ def builder(self) -> None: def inspect(self) -> None: return None - + @abstractmethod def cell_attribute_manager(self) -> og.AttributeManager: ... - \ No newline at end of file diff --git a/src/opengeodeweb_back/geode_objects/geode_grid3d.py b/src/opengeodeweb_back/geode_objects/geode_grid3d.py index 0519f6f0..0e2e2399 100644 --- a/src/opengeodeweb_back/geode_objects/geode_grid3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_grid3d.py @@ -25,6 +25,6 @@ def builder(self) -> None: def inspect(self) -> None: return None - + @abstractmethod def cell_attribute_manager(self) -> og.AttributeManager: ... diff --git a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py index a20baeb3..5a345707 100644 --- a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py @@ -67,6 +67,6 @@ def save_light_viewable(self, filename_without_extension: str) -> str: def vertex_attribute_manager(self) -> og.AttributeManager: return self.light_regular_grid.grid_vertex_attribute_manager() - + def cell_attribute_manager(self) -> og.AttributeManager: return self.light_regular_grid.cell_attribute_manager() diff --git a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py index 2591c338..e342907b 100644 --- a/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py @@ -67,6 +67,6 @@ def save_light_viewable(self, filename_without_extension: str) -> str: def vertex_attribute_manager(self) -> og.AttributeManager: return self.light_regular_grid.grid_vertex_attribute_manager() - + def cell_attribute_manager(self) -> og.AttributeManager: return self.light_regular_grid.cell_attribute_manager() diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index c621b1ae..3541a985 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -279,6 +279,7 @@ def vertex_attribute_names() -> flask.Response: 200, ) + @routes.route( schemas_dict["cell_attribute_names"]["route"], methods=schemas_dict["cell_attribute_names"]["methods"], @@ -299,6 +300,7 @@ def cell_attribute_names() -> flask.Response: 200, ) + @routes.route( schemas_dict["polygon_attribute_names"]["route"], methods=schemas_dict["polygon_attribute_names"]["methods"], From ef2e68cbbb114f899e2178c80c729236fce35c8a Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Fri, 28 Nov 2025 14:34:58 +0100 Subject: [PATCH 14/21] cell attributes & tests --- src/opengeodeweb_back/app.py | 10 +++---- .../geode_objects/__init__.py | 16 ++-------- .../geode_objects/geode_grid2d.py | 4 +-- .../geode_objects/geode_grid3d.py | 4 +-- ...lard_grid2d.py => geode_regular_grid2d.py} | 9 +++++- ...lard_grid3d.py => geode_regular_grid3d.py} | 9 +++++- .../routes/blueprint_routes.py | 10 +++---- .../routes/create/blueprint_create.py | 4 +-- .../routes/models/blueprint_models.py | 4 +-- src/opengeodeweb_back/utils_functions.py | 1 + tests/test_routes.py | 30 +++++++++++++++++++ 11 files changed, 68 insertions(+), 33 deletions(-) rename src/opengeodeweb_back/geode_objects/{geode_regulard_grid2d.py => geode_regular_grid2d.py} (89%) rename src/opengeodeweb_back/geode_objects/{geode_regulard_grid3d.py => geode_regular_grid3d.py} (88%) diff --git a/src/opengeodeweb_back/app.py b/src/opengeodeweb_back/app.py index 78fba0a4..ece0cb3e 100644 --- a/src/opengeodeweb_back/app.py +++ b/src/opengeodeweb_back/app.py @@ -72,14 +72,14 @@ def teardown_request(exception: BaseException | None) -> None: @app.errorhandler(HTTPException) -def errorhandler(e: HTTPException) -> tuple[dict[str, Any], int] | Response: - return utils_functions.handle_exception(e) +def errorhandler(exception: HTTPException) -> tuple[dict[str, Any], int] | Response: + return utils_functions.handle_exception(exception) @app.errorhandler(Exception) -def handle_generic_exception(e: Exception) -> Response: - print("handle_generic_exception:", str(e), flush=True) - return flask.make_response({"error": str(e)}, 500) +def handle_generic_exception(exception: Exception) -> Response: + print("\033[91mError:\033[0m \033[91m" + str(exception) + "\033[0m", flush=True) + return flask.make_response({"description": str(exception)}, 500) @app.route( diff --git a/src/opengeodeweb_back/geode_objects/__init__.py b/src/opengeodeweb_back/geode_objects/__init__.py index 6d41d4d6..bb32b69d 100644 --- a/src/opengeodeweb_back/geode_objects/__init__.py +++ b/src/opengeodeweb_back/geode_objects/__init__.py @@ -1,21 +1,11 @@ # Standard library imports from __future__ import annotations -from abc import ABC, abstractmethod -from typing import Literal, Any, get_args, cast # Third party imports -import opengeode as og -import opengeode_io as og_io -import opengeode_inspector as og_inspector -import opengeode_geosciences as og_gs -import opengeode_geosciencesio as og_gs_io -import geode_viewables as viewables # Local application imports -from .types import GeodeObjectType, GeodeMeshType, GeodeModelType +from .types import GeodeObjectType from .geode_object import GeodeObject -from .geode_model import GeodeModel -from .geode_mesh import GeodeMesh from .geode_brep import GeodeBRep from .geode_vertex_set import GeodeVertexSet from .geode_graph import GeodeGraph @@ -29,11 +19,11 @@ from .geode_polygonal_surface3d import GeodePolygonalSurface3D from .geode_triangulated_surface2d import GeodeTriangulatedSurface2D from .geode_triangulated_surface3d import GeodeTriangulatedSurface3D -from .geode_regulard_grid2d import GeodeRegularGrid2D +from .geode_regular_grid2d import GeodeRegularGrid2D from .geode_polyhedral_solid3d import GeodePolyhedralSolid3D from .geode_tetrahedral_solid3d import GeodeTetrahedralSolid3D from .geode_hybrid_solid3d import GeodeHybridSolid3D -from .geode_regulard_grid3d import GeodeRegularGrid3D +from .geode_regular_grid3d import GeodeRegularGrid3D from .geode_light_regular_grid2d import GeodeLightRegularGrid2D from .geode_light_regular_grid3d import GeodeLightRegularGrid3D from .geode_section import GeodeSection diff --git a/src/opengeodeweb_back/geode_objects/geode_grid2d.py b/src/opengeodeweb_back/geode_objects/geode_grid2d.py index bf1c166c..40148b1f 100644 --- a/src/opengeodeweb_back/geode_objects/geode_grid2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_grid2d.py @@ -20,10 +20,10 @@ def is_3D(cls) -> bool: def is_viewable(cls) -> bool: return True - def builder(self) -> None: + def builder(self) -> object: return None - def inspect(self) -> None: + def inspect(self) -> object: return None @abstractmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_grid3d.py b/src/opengeodeweb_back/geode_objects/geode_grid3d.py index 0519f6f0..fd3ab7f2 100644 --- a/src/opengeodeweb_back/geode_objects/geode_grid3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_grid3d.py @@ -20,10 +20,10 @@ def is_3D(cls) -> bool: def is_viewable(cls) -> bool: return True - def builder(self) -> None: + def builder(self) -> object: return None - def inspect(self) -> None: + def inspect(self) -> object: return None @abstractmethod diff --git a/src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py b/src/opengeodeweb_back/geode_objects/geode_regular_grid2d.py similarity index 89% rename from src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py rename to src/opengeodeweb_back/geode_objects/geode_regular_grid2d.py index f33fbfa7..7be697b9 100644 --- a/src/opengeodeweb_back/geode_objects/geode_regulard_grid2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_regular_grid2d.py @@ -12,7 +12,7 @@ from .geode_grid2d import GeodeGrid2D -class GeodeRegularGrid2D(GeodeSurfaceMesh2D): +class GeodeRegularGrid2D(GeodeSurfaceMesh2D, GeodeGrid2D): regular_grid: og.RegularGrid2D def __init__(self, regular_grid: og.RegularGrid2D | None = None) -> None: @@ -24,6 +24,9 @@ def __init__(self, regular_grid: og.RegularGrid2D | None = None) -> None: @classmethod def geode_object_type(cls) -> GeodeMeshType: return "RegularGrid2D" + + def inspect(self) -> og_inspector.SurfaceInspectionResult: + return super().inspect() def native_extension(self) -> str: return self.regular_grid.native_extension() @@ -70,3 +73,7 @@ def save_light_viewable(self, filename_without_extension: str) -> str: return viewables.save_light_viewable_regular_grid2D( self.regular_grid, filename_without_extension ) + + def cell_attribute_manager(self) -> og.AttributeManager: + return self.regular_grid.cell_attribute_manager() + diff --git a/src/opengeodeweb_back/geode_objects/geode_regulard_grid3d.py b/src/opengeodeweb_back/geode_objects/geode_regular_grid3d.py similarity index 88% rename from src/opengeodeweb_back/geode_objects/geode_regulard_grid3d.py rename to src/opengeodeweb_back/geode_objects/geode_regular_grid3d.py index 7ed0d6c0..b351511a 100644 --- a/src/opengeodeweb_back/geode_objects/geode_regulard_grid3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_regular_grid3d.py @@ -9,9 +9,10 @@ # Local application imports from .types import GeodeMeshType from .geode_solid_mesh3d import GeodeSolidMesh3D +from .geode_grid3d import GeodeGrid3D -class GeodeRegularGrid3D(GeodeSolidMesh3D): +class GeodeRegularGrid3D(GeodeSolidMesh3D, GeodeGrid3D): regular_grid: og.RegularGrid3D def __init__(self, regular_grid: og.RegularGrid3D | None = None) -> None: @@ -69,3 +70,9 @@ def save_light_viewable(self, filename_without_extension: str) -> str: return viewables.save_light_viewable_regular_grid3D( self.regular_grid, filename_without_extension ) + + def cell_attribute_manager(self) -> og.AttributeManager: + return self.regular_grid.cell_attribute_manager() + + def inspect(self) -> og_inspector.SolidInspectionResult: + return super().inspect() \ No newline at end of file diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index c621b1ae..def916cf 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -254,7 +254,7 @@ def texture_coordinates() -> flask.Response: params = schemas.TextureCoordinates.from_dict(json_data) geode_object = geode_functions.load_geode_object(params.id) if not isinstance(geode_object, GeodeSurfaceMesh2D | GeodeSurfaceMesh3D): - flask.abort(500, f"{params.id} is not a GeodeSurfaceMesh") + flask.abort(400, f"{params.id} is not a GeodeSurfaceMesh") texture_coordinates = geode_object.texture_manager().texture_names() return flask.make_response({"texture_coordinates": texture_coordinates}, 200) @@ -270,7 +270,7 @@ def vertex_attribute_names() -> flask.Response: params = schemas.VertexAttributeNames.from_dict(json_data) geode_object = geode_functions.load_geode_object(params.id) if not isinstance(geode_object, GeodeMesh): - flask.abort(500, f"{params.id} is not a GeodeMesh") + flask.abort(400, f"{params.id} is not a GeodeMesh") vertex_attribute_names = geode_object.vertex_attribute_manager().attribute_names() return flask.make_response( { @@ -290,7 +290,7 @@ def cell_attribute_names() -> flask.Response: params = schemas.PolygonAttributeNames.from_dict(json_data) geode_object = geode_functions.load_geode_object(params.id) if not isinstance(geode_object, GeodeGrid2D | GeodeGrid3D): - flask.abort(500, f"{params.id} is not a GeodeGrid") + flask.abort(400, f"{params.id} is not a GeodeGrid") cell_attribute_names = geode_object.cell_attribute_manager().attribute_names() return flask.make_response( { @@ -310,7 +310,7 @@ def polygon_attribute_names() -> flask.Response: params = schemas.PolygonAttributeNames.from_dict(json_data) geode_object = geode_functions.load_geode_object(params.id) if not isinstance(geode_object, GeodeSurfaceMesh2D | GeodeSurfaceMesh3D): - flask.abort(500, f"{params.id} is not a GeodeSurfaceMesh") + flask.abort(400, f"{params.id} is not a GeodeSurfaceMesh") polygon_attribute_names = geode_object.polygon_attribute_manager().attribute_names() return flask.make_response( { @@ -331,7 +331,7 @@ def polyhedron_attribute_names() -> flask.Response: params = schemas.PolyhedronAttributeNames.from_dict(json_data) geode_object = geode_functions.load_geode_object(params.id) if not isinstance(geode_object, GeodeSolidMesh3D): - flask.abort(500, f"{params.id} is not a GeodeSolidMesh") + flask.abort(400, f"{params.id} is not a GeodeSolidMesh") polyhedron_attribute_names = ( geode_object.polyhedron_attribute_manager().attribute_names() ) diff --git a/src/opengeodeweb_back/routes/create/blueprint_create.py b/src/opengeodeweb_back/routes/create/blueprint_create.py index 04e7448a..2b49a83d 100644 --- a/src/opengeodeweb_back/routes/create/blueprint_create.py +++ b/src/opengeodeweb_back/routes/create/blueprint_create.py @@ -82,11 +82,11 @@ def create_voi() -> flask.Response: aoi_data = geode_functions.get_data_info(params.aoi_id) if not aoi_data: - flask.abort(500, f"AOI with id {params.aoi_id} not found") + flask.abort(404, f"AOI with id {params.aoi_id} not found") aoi_object = geode_functions.load_geode_object(params.aoi_id) if not isinstance(aoi_object, GeodeEdgedCurve3D): - flask.abort(500, f"AOI with id {params.aoi_id} not a GeodeEdgedCurve3D") + flask.abort(400, f"AOI with id {params.aoi_id} is not a GeodeEdgedCurve3D") aoi_curve = aoi_object.edged_curve nb_points = aoi_curve.nb_vertices() diff --git a/src/opengeodeweb_back/routes/models/blueprint_models.py b/src/opengeodeweb_back/routes/models/blueprint_models.py index 4ad53586..ab052745 100644 --- a/src/opengeodeweb_back/routes/models/blueprint_models.py +++ b/src/opengeodeweb_back/routes/models/blueprint_models.py @@ -24,7 +24,7 @@ def uuid_to_flat_index() -> flask.Response: tree = ET.parse(vtm_file_path) root = tree.find("vtkMultiBlockDataSet") if root is None: - raise Exception("Failed to read viewable file") + flask.abort(500, "Failed to read viewable file") uuid_to_flat_index = {} current_index = 0 for elem in root.iter(): @@ -45,7 +45,7 @@ def extract_uuids_endpoint() -> flask.Response: params = schemas.MeshComponents.from_dict(json_data) model = geode_functions.load_geode_object(params.id) if not isinstance(model, GeodeModel): - flask.abort(500, f"{params.id} is not a GeodeModel") + flask.abort(400, f"{params.id} is not a GeodeModel") mesh_components = model.mesh_components() uuid_dict = {} for mesh_component, ids in mesh_components.items(): diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index ad516c52..9e2e553a 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -164,6 +164,7 @@ def send_file( def handle_exception(exception: HTTPException) -> flask.Response: + print("\033[91mError:\033[0m \033[91m" + str(exception) + "\033[0m", flush=True) response = flask.jsonify( { "code": exception.code, diff --git a/tests/test_routes.py b/tests/test_routes.py index 9625657c..1de5a172 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -16,6 +16,10 @@ GeodePolyhedralSolid3D, ) +from opengeodeweb_back.geode_objects.geode_regular_grid2d import ( + GeodeRegularGrid2D, +) + base_dir = os.path.abspath(os.path.dirname(__file__)) data_dir = os.path.join(base_dir, "data") @@ -237,6 +241,32 @@ def test_vertex_attribute_names(client: FlaskClient, test_id: str) -> None: assert type(vertex_attribute_name) is str +def test_cell_attribute_names(client: FlaskClient, test_id: str) -> None: + route = f"/opengeodeweb_back/cell_attribute_names" + + with client.application.app_context(): + file = os.path.join(data_dir, "test.og_rgd2d") + data = Data.create( + geode_object=GeodeRegularGrid2D.geode_object_type(), + viewer_object=GeodeRegularGrid2D.viewer_type(), + input_file=file, + ) + data.native_file_name = file + session = get_session() + if session: + session.commit() + + data_path = geode_functions.data_file_path(data.id, data.native_file_name) + os.makedirs(os.path.dirname(data_path), exist_ok=True) + assert os.path.exists(data_path), f"File not found at {data_path}" + response = client.post(route, json={"id": data.id}) + assert response.status_code == 200 + cell_attribute_names = response.get_json()["cell_attribute_names"] + assert type(cell_attribute_names) is list + for cell_attribute_name in cell_attribute_names: + assert type(cell_attribute_name) is str + + def test_polygon_attribute_names(client: FlaskClient, test_id: str) -> None: route = f"/opengeodeweb_back/polygon_attribute_names" From 77d16801d0536cd5d5bd1f20f88f66b3a23f2ed5 Mon Sep 17 00:00:00 2001 From: JulienChampagnol <91873154+JulienChampagnol@users.noreply.github.com> Date: Fri, 28 Nov 2025 13:35:42 +0000 Subject: [PATCH 15/21] Apply prepare changes --- src/opengeodeweb_back/app.py | 2 +- src/opengeodeweb_back/geode_objects/geode_regular_grid2d.py | 5 ++--- src/opengeodeweb_back/geode_objects/geode_regular_grid3d.py | 4 ++-- src/opengeodeweb_back/routes/blueprint_routes.py | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/opengeodeweb_back/app.py b/src/opengeodeweb_back/app.py index ece0cb3e..0b9cd81b 100644 --- a/src/opengeodeweb_back/app.py +++ b/src/opengeodeweb_back/app.py @@ -77,7 +77,7 @@ def errorhandler(exception: HTTPException) -> tuple[dict[str, Any], int] | Respo @app.errorhandler(Exception) -def handle_generic_exception(exception: Exception) -> Response: +def handle_generic_exception(exception: Exception) -> Response: print("\033[91mError:\033[0m \033[91m" + str(exception) + "\033[0m", flush=True) return flask.make_response({"description": str(exception)}, 500) diff --git a/src/opengeodeweb_back/geode_objects/geode_regular_grid2d.py b/src/opengeodeweb_back/geode_objects/geode_regular_grid2d.py index 7be697b9..7fa45e07 100644 --- a/src/opengeodeweb_back/geode_objects/geode_regular_grid2d.py +++ b/src/opengeodeweb_back/geode_objects/geode_regular_grid2d.py @@ -24,7 +24,7 @@ def __init__(self, regular_grid: og.RegularGrid2D | None = None) -> None: @classmethod def geode_object_type(cls) -> GeodeMeshType: return "RegularGrid2D" - + def inspect(self) -> og_inspector.SurfaceInspectionResult: return super().inspect() @@ -73,7 +73,6 @@ def save_light_viewable(self, filename_without_extension: str) -> str: return viewables.save_light_viewable_regular_grid2D( self.regular_grid, filename_without_extension ) - + def cell_attribute_manager(self) -> og.AttributeManager: return self.regular_grid.cell_attribute_manager() - diff --git a/src/opengeodeweb_back/geode_objects/geode_regular_grid3d.py b/src/opengeodeweb_back/geode_objects/geode_regular_grid3d.py index b351511a..8f158ca4 100644 --- a/src/opengeodeweb_back/geode_objects/geode_regular_grid3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_regular_grid3d.py @@ -73,6 +73,6 @@ def save_light_viewable(self, filename_without_extension: str) -> str: def cell_attribute_manager(self) -> og.AttributeManager: return self.regular_grid.cell_attribute_manager() - + def inspect(self) -> og_inspector.SolidInspectionResult: - return super().inspect() \ No newline at end of file + return super().inspect() diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index a6c178ed..65a63a31 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -291,7 +291,7 @@ def cell_attribute_names() -> flask.Response: params = schemas.PolygonAttributeNames.from_dict(json_data) geode_object = geode_functions.load_geode_object(params.id) if not isinstance(geode_object, GeodeGrid2D | GeodeGrid3D): - flask.abort(400, f"{params.id} is not a GeodeGrid") + flask.abort(400, f"{params.id} is not a GeodeGrid") cell_attribute_names = geode_object.cell_attribute_manager().attribute_names() return flask.make_response( { From aee475806d0ba78f7451a330acc8e9ab7f96a89e Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Fri, 28 Nov 2025 14:53:22 +0100 Subject: [PATCH 16/21] debug default=FLASK_DEBUG --- src/opengeodeweb_back/app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/opengeodeweb_back/app.py b/src/opengeodeweb_back/app.py index ece0cb3e..f3b270a4 100644 --- a/src/opengeodeweb_back/app.py +++ b/src/opengeodeweb_back/app.py @@ -115,7 +115,7 @@ def run_server() -> None: parser.add_argument( "-d", "--debug", - default=True, + default=FLASK_DEBUG, help="Whether to run in debug mode", action="store_true", ) @@ -149,7 +149,7 @@ def run_server() -> None: app.config.update(DATA_FOLDER_PATH=args.data_folder_path) app.config.update(UPLOAD_FOLDER=args.upload_folder_path) app.config.update(MINUTES_BEFORE_TIMEOUT=args.timeout) - flask_cors.CORS(app, origins=args.allowed_origins, methods=["GET", "POST", "PUT"]) + flask_cors.CORS(app, origins=args.allowed_origins) print( f"Host: {args.host}, Port: {args.port}, Debug: {args.debug}, " f"Data folder path: {args.data_folder_path}, Timeout: {args.timeout}, " From a3d23fac05bad1fbb8a0176a4d5354e475fa7ded Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Fri, 28 Nov 2025 15:12:38 +0100 Subject: [PATCH 17/21] viewable_filename & native_filename harmonize --- src/opengeodeweb_back/geode_functions.py | 2 +- .../routes/blueprint_routes.py | 2 +- src/opengeodeweb_back/utils_functions.py | 12 +++---- tests/test_create_routes.py | 8 ++--- tests/test_models_routes.py | 10 +++--- tests/test_routes.py | 28 +++++++-------- tests/test_utils_functions.py | 34 +++++++++---------- 7 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/opengeodeweb_back/geode_functions.py b/src/opengeodeweb_back/geode_functions.py index f573bf84..710f0f99 100644 --- a/src/opengeodeweb_back/geode_functions.py +++ b/src/opengeodeweb_back/geode_functions.py @@ -37,7 +37,7 @@ def load_geode_object(data_id: str) -> GeodeObject: if not data: flask.abort(404, f"Data with id {data_id} not found") - file_absolute_path = data_file_path(data_id, data.native_file_name) + file_absolute_path = data_file_path(data_id, data.native_filename) print("Loading file: ", file_absolute_path) print("File exists: ", os.path.exists(file_absolute_path)) return geode_object_from_string(data.geode_object).load(file_absolute_path) diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index 65a63a31..ac472890 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -473,7 +473,7 @@ def import_project() -> flask.Response: with get_session() as session: for data in rows: data_path = geode_functions.data_file_path(data.id) - viewable_name = data.viewable_file_name + viewable_name = data.viewable_filename if viewable_name: vpath = geode_functions.data_file_path(data.id, viewable_name) if os.path.isfile(vpath): diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index 9e2e553a..ef266098 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -208,15 +208,15 @@ def save_all_viewables_and_return_info( ) with open(light_path, "rb") as f: binary_light_viewable = f.read() - data.native_file_name = os.path.basename(native_files[0]) - data.viewable_file_name = os.path.basename(viewable_path) + data.native_filename = os.path.basename(native_files[0]) + data.viewable_filename = os.path.basename(viewable_path) data.light_viewable = os.path.basename(light_path) - assert data.native_file_name is not None - assert data.viewable_file_name is not None + assert data.native_filename is not None + assert data.viewable_filename is not None assert data.light_viewable is not None return { - "native_file_name": data.native_file_name, - "viewable_file_name": data.viewable_file_name, + "native_filename": data.native_filename, + "viewable_filename": data.viewable_filename, "id": data.id, "name": geode_object.identifier.name(), "viewer_type": data.viewer_object, diff --git a/tests/test_create_routes.py b/tests/test_create_routes.py index dd8e2d8b..7f811162 100644 --- a/tests/test_create_routes.py +++ b/tests/test_create_routes.py @@ -51,10 +51,10 @@ def test_create_point(client: FlaskClient, point_data: test_utils.JsonData) -> N # Verify response data response_data = response.get_json() - assert "viewable_file_name" in response_data + assert "viewable_filename" in response_data assert "id" in response_data assert "name" in response_data - assert "native_file_name" in response_data + assert "native_filename" in response_data assert "viewer_type" in response_data assert "geode_object_type" in response_data @@ -76,10 +76,10 @@ def test_create_aoi(client: FlaskClient, aoi_data: test_utils.JsonData) -> None: # Verify response data response_data = response.get_json() - assert "viewable_file_name" in response_data + assert "viewable_filename" in response_data assert "id" in response_data assert "name" in response_data - assert "native_file_name" in response_data + assert "native_filename" in response_data assert "viewer_type" in response_data assert "geode_object_type" in response_data diff --git a/tests/test_models_routes.py b/tests/test_models_routes.py index 47f4f606..16aaed6f 100644 --- a/tests/test_models_routes.py +++ b/tests/test_models_routes.py @@ -46,7 +46,7 @@ def test_extract_brep_uuids(client: FlaskClient, test_id: str) -> None: viewer_object=GeodeBRep.viewer_type(), input_file=brep_filename, ) - data.native_file_name = brep_filename + data.native_filename = brep_filename session = get_session() if session: session.commit() @@ -106,8 +106,8 @@ def test_import_project_route(client: FlaskClient, tmp_path: Path) -> None: temp_db = tmp_path / "temp_project.db" conn = sqlite3.connect(str(temp_db)) conn.execute( - "CREATE TABLE datas (id TEXT PRIMARY KEY, geode_object TEXT, viewer_object TEXT, native_file_name TEXT, " - "viewable_file_name TEXT, light_viewable TEXT, input_file TEXT, additional_files TEXT)" + "CREATE TABLE datas (id TEXT PRIMARY KEY, geode_object TEXT, viewer_object TEXT, native_filename TEXT, " + "viewable_filename TEXT, light_viewable TEXT, input_file TEXT, additional_files TEXT)" ) conn.commit() conn.close() @@ -154,7 +154,7 @@ def test_save_viewable_workflow_from_file(client: FlaskClient) -> None: data_id = response.get_json()["id"] assert isinstance(data_id, str) and len(data_id) > 0 - assert response.get_json()["viewable_file_name"].endswith(".vtm") + assert response.get_json()["viewable_filename"].endswith(".vtm") comp_resp = client.post( "/opengeodeweb_back/models/vtm_component_indices", json={"id": data_id} @@ -184,4 +184,4 @@ def test_save_viewable_workflow_from_object(client: FlaskClient) -> None: data_id = response.get_json()["id"] assert isinstance(data_id, str) and len(data_id) > 0 assert response.get_json()["geode_object_type"] == "EdgedCurve3D" - assert response.get_json()["viewable_file_name"].endswith(".vtp") + assert response.get_json()["viewable_filename"].endswith(".vtp") diff --git a/tests/test_routes.py b/tests/test_routes.py index 1de5a172..dfcca6fe 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -173,10 +173,10 @@ def get_full_data() -> test_utils.JsonData: # Normal test with filename 'corbi.og_brep' response = client.post(route, json=get_full_data()) assert response.status_code == 200 - native_file_name = response.get_json()["native_file_name"] - assert type(native_file_name) is str - viewable_file_name = response.get_json()["viewable_file_name"] - assert type(viewable_file_name) is str + native_filename = response.get_json()["native_filename"] + assert type(native_filename) is str + viewable_filename = response.get_json()["viewable_filename"] + assert type(viewable_filename) is str id = response.get_json().get("id") assert type(id) is str object_type = response.get_json()["viewer_type"] @@ -197,12 +197,12 @@ def test_texture_coordinates(client: FlaskClient, test_id: str) -> None: viewer_object=GeodePolygonalSurface3D.viewer_type(), input_file=file, ) - data.native_file_name = file + data.native_filename = file session = get_session() if session: session.commit() - data_path = geode_functions.data_file_path(data.id, data.native_file_name) + data_path = geode_functions.data_file_path(data.id, data.native_filename) os.makedirs(os.path.dirname(data_path), exist_ok=True) assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post( @@ -225,12 +225,12 @@ def test_vertex_attribute_names(client: FlaskClient, test_id: str) -> None: viewer_object=GeodePolygonalSurface3D.viewer_type(), input_file=file, ) - data.native_file_name = file + data.native_filename = file session = get_session() if session: session.commit() - data_path = geode_functions.data_file_path(data.id, data.native_file_name) + data_path = geode_functions.data_file_path(data.id, data.native_filename) os.makedirs(os.path.dirname(data_path), exist_ok=True) assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) @@ -251,12 +251,12 @@ def test_cell_attribute_names(client: FlaskClient, test_id: str) -> None: viewer_object=GeodeRegularGrid2D.viewer_type(), input_file=file, ) - data.native_file_name = file + data.native_filename = file session = get_session() if session: session.commit() - data_path = geode_functions.data_file_path(data.id, data.native_file_name) + data_path = geode_functions.data_file_path(data.id, data.native_filename) os.makedirs(os.path.dirname(data_path), exist_ok=True) assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) @@ -277,12 +277,12 @@ def test_polygon_attribute_names(client: FlaskClient, test_id: str) -> None: viewer_object=GeodePolygonalSurface3D.viewer_type(), input_file=file, ) - data.native_file_name = file + data.native_filename = file session = get_session() if session: session.commit() - data_path = geode_functions.data_file_path(data.id, data.native_file_name) + data_path = geode_functions.data_file_path(data.id, data.native_filename) os.makedirs(os.path.dirname(data_path), exist_ok=True) assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) @@ -303,12 +303,12 @@ def test_polyhedron_attribute_names(client: FlaskClient, test_id: str) -> None: viewer_object=GeodePolyhedralSolid3D.viewer_type(), input_file=file, ) - data.native_file_name = file + data.native_filename = file session = get_session() if session: session.commit() - data_path = geode_functions.data_file_path(data.id, data.native_file_name) + data_path = geode_functions.data_file_path(data.id, data.native_filename) os.makedirs(os.path.dirname(data_path), exist_ok=True) assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) diff --git a/tests/test_utils_functions.py b/tests/test_utils_functions.py index 4710a070..51bd09dc 100644 --- a/tests/test_utils_functions.py +++ b/tests/test_utils_functions.py @@ -123,12 +123,12 @@ def test_save_all_viewables_and_return_info(client: FlaskClient) -> None: ) assert isinstance(result, dict) - native_file_name = result["native_file_name"] - assert isinstance(native_file_name, str) - assert native_file_name.startswith("native.") - viewable_file_name = result["viewable_file_name"] - assert isinstance(viewable_file_name, str) - assert viewable_file_name.endswith(".vtm") + native_filename = result["native_filename"] + assert isinstance(native_filename, str) + assert native_filename.startswith("native.") + viewable_filename = result["viewable_filename"] + assert isinstance(viewable_filename, str) + assert viewable_filename.endswith(".vtm") assert isinstance(result["id"], str) assert len(result["id"]) == 32 assert re.match(r"[0-9a-f]{32}", result["id"]) @@ -139,8 +139,8 @@ def test_save_all_viewables_and_return_info(client: FlaskClient) -> None: db_entry = Data.get(result["id"]) assert db_entry is not None - assert db_entry.native_file_name == result["native_file_name"] - assert db_entry.viewable_file_name == result["viewable_file_name"] + assert db_entry.native_filename == result["native_filename"] + assert db_entry.viewable_filename == result["viewable_filename"] assert db_entry.geode_object == geode_object.geode_object_type() assert db_entry.input_file == input_file assert db_entry.additional_files == additional_files @@ -169,7 +169,7 @@ def test_save_all_viewables_commits_to_db(client: FlaskClient) -> None: assert isinstance(data_id, str) db_entry_before = Data.get(data_id) assert db_entry_before is not None - assert db_entry_before.native_file_name == result["native_file_name"] + assert db_entry_before.native_filename == result["native_filename"] def test_generate_native_viewable_and_light_viewable_from_object( @@ -186,10 +186,10 @@ def test_generate_native_viewable_and_light_viewable_from_object( ) assert isinstance(result, dict) - assert isinstance(result["native_file_name"], str) - assert result["native_file_name"].startswith("native.") - assert isinstance(result["viewable_file_name"], str) - assert result["viewable_file_name"].endswith(".vtm") + assert isinstance(result["native_filename"], str) + assert result["native_filename"].startswith("native.") + assert isinstance(result["viewable_filename"], str) + assert result["viewable_filename"].endswith(".vtm") assert isinstance(result["id"], str) assert re.match(r"[0-9a-f]{32}", result["id"]) assert isinstance(result["viewer_type"], str) @@ -207,10 +207,10 @@ def test_generate_native_viewable_and_light_viewable_from_file( ) assert isinstance(result, dict) - assert isinstance(result["native_file_name"], str) - assert result["native_file_name"].startswith("native.") - assert isinstance(result["viewable_file_name"], str) - assert result["viewable_file_name"].endswith(".vtm") + assert isinstance(result["native_filename"], str) + assert result["native_filename"].startswith("native.") + assert isinstance(result["viewable_filename"], str) + assert result["viewable_filename"].endswith(".vtm") assert isinstance(result["id"], str) assert re.match(r"[0-9a-f]{32}", result["id"]) assert isinstance(result["viewer_type"], str) From e85cea6cb0c62c65837c5d919a58fd788f26f19f Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Fri, 28 Nov 2025 16:11:13 +0100 Subject: [PATCH 18/21] filename -> file --- src/opengeodeweb_back/geode_functions.py | 7 +--- .../routes/blueprint_routes.py | 4 +- src/opengeodeweb_back/utils_functions.py | 23 ++++++----- tests/test_create_routes.py | 9 ++--- tests/test_models_routes.py | 10 ++--- tests/test_routes.py | 28 +++++++------- tests/test_utils_functions.py | 38 +++++++++---------- 7 files changed, 55 insertions(+), 64 deletions(-) diff --git a/src/opengeodeweb_back/geode_functions.py b/src/opengeodeweb_back/geode_functions.py index 710f0f99..afcd2e1c 100644 --- a/src/opengeodeweb_back/geode_functions.py +++ b/src/opengeodeweb_back/geode_functions.py @@ -2,11 +2,8 @@ import os # Third party imports -import opengeode_geosciences as og_gs -import opengeode as og import werkzeug import flask -from typing import Any # Local application imports from .geode_objects import geode_objects @@ -15,9 +12,7 @@ geode_object_type, ) from .geode_objects.geode_object import GeodeObject -from . import utils_functions from opengeodeweb_microservice.database.data import Data -from opengeodeweb_microservice.database.connection import get_session def data_file_path(data_id: str, filename: str | None = None) -> str: @@ -37,7 +32,7 @@ def load_geode_object(data_id: str) -> GeodeObject: if not data: flask.abort(404, f"Data with id {data_id} not found") - file_absolute_path = data_file_path(data_id, data.native_filename) + file_absolute_path = data_file_path(data_id, data.native_file) print("Loading file: ", file_absolute_path) print("File exists: ", os.path.exists(file_absolute_path)) return geode_object_from_string(data.geode_object).load(file_absolute_path) diff --git a/src/opengeodeweb_back/routes/blueprint_routes.py b/src/opengeodeweb_back/routes/blueprint_routes.py index ac472890..654c1116 100644 --- a/src/opengeodeweb_back/routes/blueprint_routes.py +++ b/src/opengeodeweb_back/routes/blueprint_routes.py @@ -237,7 +237,7 @@ def save_viewable_file() -> flask.Response: return flask.make_response( utils_functions.generate_native_viewable_and_light_viewable_from_file( geode_object_type=geode_object_type(params.geode_object_type), - input_filename=params.filename, + input_file=params.filename, ), 200, ) @@ -473,7 +473,7 @@ def import_project() -> flask.Response: with get_session() as session: for data in rows: data_path = geode_functions.data_file_path(data.id) - viewable_name = data.viewable_filename + viewable_name = data.viewable_file if viewable_name: vpath = geode_functions.data_file_path(data.id, viewable_name) if os.path.isfile(vpath): diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index ef266098..7099f54e 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -1,11 +1,10 @@ # Standard library imports -import json import os import threading import time import zipfile from collections.abc import Callable -from concurrent.futures import ThreadPoolExecutor, Future +from concurrent.futures import ThreadPoolExecutor # Third party imports import flask @@ -208,15 +207,15 @@ def save_all_viewables_and_return_info( ) with open(light_path, "rb") as f: binary_light_viewable = f.read() - data.native_filename = os.path.basename(native_files[0]) - data.viewable_filename = os.path.basename(viewable_path) + data.native_file = os.path.basename(native_files[0]) + data.viewable_file = os.path.basename(viewable_path) data.light_viewable = os.path.basename(light_path) - assert data.native_filename is not None - assert data.viewable_filename is not None + assert data.native_file is not None + assert data.viewable_file is not None assert data.light_viewable is not None return { - "native_filename": data.native_filename, - "viewable_filename": data.viewable_filename, + "native_file": data.native_file, + "viewable_file": data.viewable_file, "id": data.id, "name": geode_object.identifier.name(), "viewer_type": data.viewer_object, @@ -239,20 +238,20 @@ def generate_native_viewable_and_light_viewable_from_object( def generate_native_viewable_and_light_viewable_from_file( - geode_object_type: GeodeObjectType, input_filename: str + geode_object_type: GeodeObjectType, input_file: str ) -> dict[str, str | list[str]]: generic_geode_object = geode_objects[geode_object_type] data = Data.create( geode_object=geode_object_type, viewer_object=generic_geode_object.viewer_type(), - input_file=input_filename, + input_file=input_file, ) data_path = create_data_folder_from_id(data.id) - full_input_filename = geode_functions.upload_file_path(input_filename) + full_input_filename = geode_functions.upload_file_path(input_file) copied_full_path = os.path.join( - data_path, werkzeug.utils.secure_filename(input_filename) + data_path, werkzeug.utils.secure_filename(input_file) ) shutil.copy2(full_input_filename, copied_full_path) diff --git a/tests/test_create_routes.py b/tests/test_create_routes.py index 7f811162..61b1eb42 100644 --- a/tests/test_create_routes.py +++ b/tests/test_create_routes.py @@ -1,5 +1,4 @@ # Standard library imports -import os import uuid # Third party imports @@ -51,10 +50,10 @@ def test_create_point(client: FlaskClient, point_data: test_utils.JsonData) -> N # Verify response data response_data = response.get_json() - assert "viewable_filename" in response_data + assert "viewable_file" in response_data assert "id" in response_data assert "name" in response_data - assert "native_filename" in response_data + assert "native_file" in response_data assert "viewer_type" in response_data assert "geode_object_type" in response_data @@ -76,10 +75,10 @@ def test_create_aoi(client: FlaskClient, aoi_data: test_utils.JsonData) -> None: # Verify response data response_data = response.get_json() - assert "viewable_filename" in response_data + assert "viewable_file" in response_data assert "id" in response_data assert "name" in response_data - assert "native_filename" in response_data + assert "native_file" in response_data assert "viewer_type" in response_data assert "geode_object_type" in response_data diff --git a/tests/test_models_routes.py b/tests/test_models_routes.py index 16aaed6f..a4a2f571 100644 --- a/tests/test_models_routes.py +++ b/tests/test_models_routes.py @@ -46,7 +46,7 @@ def test_extract_brep_uuids(client: FlaskClient, test_id: str) -> None: viewer_object=GeodeBRep.viewer_type(), input_file=brep_filename, ) - data.native_filename = brep_filename + data.native_file = brep_filename session = get_session() if session: session.commit() @@ -106,8 +106,8 @@ def test_import_project_route(client: FlaskClient, tmp_path: Path) -> None: temp_db = tmp_path / "temp_project.db" conn = sqlite3.connect(str(temp_db)) conn.execute( - "CREATE TABLE datas (id TEXT PRIMARY KEY, geode_object TEXT, viewer_object TEXT, native_filename TEXT, " - "viewable_filename TEXT, light_viewable TEXT, input_file TEXT, additional_files TEXT)" + "CREATE TABLE datas (id TEXT PRIMARY KEY, geode_object TEXT, viewer_object TEXT, native_file TEXT, " + "viewable_file TEXT, light_viewable TEXT, input_file TEXT, additional_files TEXT)" ) conn.commit() conn.close() @@ -154,7 +154,7 @@ def test_save_viewable_workflow_from_file(client: FlaskClient) -> None: data_id = response.get_json()["id"] assert isinstance(data_id, str) and len(data_id) > 0 - assert response.get_json()["viewable_filename"].endswith(".vtm") + assert response.get_json()["viewable_file"].endswith(".vtm") comp_resp = client.post( "/opengeodeweb_back/models/vtm_component_indices", json={"id": data_id} @@ -184,4 +184,4 @@ def test_save_viewable_workflow_from_object(client: FlaskClient) -> None: data_id = response.get_json()["id"] assert isinstance(data_id, str) and len(data_id) > 0 assert response.get_json()["geode_object_type"] == "EdgedCurve3D" - assert response.get_json()["viewable_filename"].endswith(".vtp") + assert response.get_json()["viewable_file"].endswith(".vtp") diff --git a/tests/test_routes.py b/tests/test_routes.py index dfcca6fe..69c42c9f 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -173,10 +173,10 @@ def get_full_data() -> test_utils.JsonData: # Normal test with filename 'corbi.og_brep' response = client.post(route, json=get_full_data()) assert response.status_code == 200 - native_filename = response.get_json()["native_filename"] - assert type(native_filename) is str - viewable_filename = response.get_json()["viewable_filename"] - assert type(viewable_filename) is str + native_file = response.get_json()["native_file"] + assert type(native_file) is str + viewable_file = response.get_json()["viewable_file"] + assert type(viewable_file) is str id = response.get_json().get("id") assert type(id) is str object_type = response.get_json()["viewer_type"] @@ -197,12 +197,12 @@ def test_texture_coordinates(client: FlaskClient, test_id: str) -> None: viewer_object=GeodePolygonalSurface3D.viewer_type(), input_file=file, ) - data.native_filename = file + data.native_file = file session = get_session() if session: session.commit() - data_path = geode_functions.data_file_path(data.id, data.native_filename) + data_path = geode_functions.data_file_path(data.id, data.native_file) os.makedirs(os.path.dirname(data_path), exist_ok=True) assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post( @@ -225,12 +225,12 @@ def test_vertex_attribute_names(client: FlaskClient, test_id: str) -> None: viewer_object=GeodePolygonalSurface3D.viewer_type(), input_file=file, ) - data.native_filename = file + data.native_file = file session = get_session() if session: session.commit() - data_path = geode_functions.data_file_path(data.id, data.native_filename) + data_path = geode_functions.data_file_path(data.id, data.native_file) os.makedirs(os.path.dirname(data_path), exist_ok=True) assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) @@ -251,12 +251,12 @@ def test_cell_attribute_names(client: FlaskClient, test_id: str) -> None: viewer_object=GeodeRegularGrid2D.viewer_type(), input_file=file, ) - data.native_filename = file + data.native_file = file session = get_session() if session: session.commit() - data_path = geode_functions.data_file_path(data.id, data.native_filename) + data_path = geode_functions.data_file_path(data.id, data.native_file) os.makedirs(os.path.dirname(data_path), exist_ok=True) assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) @@ -277,12 +277,12 @@ def test_polygon_attribute_names(client: FlaskClient, test_id: str) -> None: viewer_object=GeodePolygonalSurface3D.viewer_type(), input_file=file, ) - data.native_filename = file + data.native_file = file session = get_session() if session: session.commit() - data_path = geode_functions.data_file_path(data.id, data.native_filename) + data_path = geode_functions.data_file_path(data.id, data.native_file) os.makedirs(os.path.dirname(data_path), exist_ok=True) assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) @@ -303,12 +303,12 @@ def test_polyhedron_attribute_names(client: FlaskClient, test_id: str) -> None: viewer_object=GeodePolyhedralSolid3D.viewer_type(), input_file=file, ) - data.native_filename = file + data.native_file = file session = get_session() if session: session.commit() - data_path = geode_functions.data_file_path(data.id, data.native_filename) + data_path = geode_functions.data_file_path(data.id, data.native_file) os.makedirs(os.path.dirname(data_path), exist_ok=True) assert os.path.exists(data_path), f"File not found at {data_path}" response = client.post(route, json={"id": data.id}) diff --git a/tests/test_utils_functions.py b/tests/test_utils_functions.py index 51bd09dc..905217b1 100644 --- a/tests/test_utils_functions.py +++ b/tests/test_utils_functions.py @@ -9,13 +9,11 @@ import shutil import uuid import zipfile -import io from pathlib import Path # Local application imports from opengeodeweb_microservice.database.data import Data -from opengeodeweb_microservice.database.connection import get_session -from opengeodeweb_back import geode_functions, utils_functions +from opengeodeweb_back import utils_functions from opengeodeweb_back.geode_objects.geode_brep import GeodeBRep base_dir = os.path.abspath(os.path.dirname(__file__)) @@ -123,12 +121,12 @@ def test_save_all_viewables_and_return_info(client: FlaskClient) -> None: ) assert isinstance(result, dict) - native_filename = result["native_filename"] - assert isinstance(native_filename, str) - assert native_filename.startswith("native.") - viewable_filename = result["viewable_filename"] - assert isinstance(viewable_filename, str) - assert viewable_filename.endswith(".vtm") + native_file = result["native_file"] + assert isinstance(native_file, str) + assert native_file.startswith("native.") + viewable_file = result["viewable_file"] + assert isinstance(viewable_file, str) + assert viewable_file.endswith(".vtm") assert isinstance(result["id"], str) assert len(result["id"]) == 32 assert re.match(r"[0-9a-f]{32}", result["id"]) @@ -139,8 +137,8 @@ def test_save_all_viewables_and_return_info(client: FlaskClient) -> None: db_entry = Data.get(result["id"]) assert db_entry is not None - assert db_entry.native_filename == result["native_filename"] - assert db_entry.viewable_filename == result["viewable_filename"] + assert db_entry.native_file == result["native_file"] + assert db_entry.viewable_file == result["viewable_file"] assert db_entry.geode_object == geode_object.geode_object_type() assert db_entry.input_file == input_file assert db_entry.additional_files == additional_files @@ -169,7 +167,7 @@ def test_save_all_viewables_commits_to_db(client: FlaskClient) -> None: assert isinstance(data_id, str) db_entry_before = Data.get(data_id) assert db_entry_before is not None - assert db_entry_before.native_filename == result["native_filename"] + assert db_entry_before.native_file == result["native_file"] def test_generate_native_viewable_and_light_viewable_from_object( @@ -186,10 +184,10 @@ def test_generate_native_viewable_and_light_viewable_from_object( ) assert isinstance(result, dict) - assert isinstance(result["native_filename"], str) - assert result["native_filename"].startswith("native.") - assert isinstance(result["viewable_filename"], str) - assert result["viewable_filename"].endswith(".vtm") + assert isinstance(result["native_file"], str) + assert result["native_file"].startswith("native.") + assert isinstance(result["viewable_file"], str) + assert result["viewable_file"].endswith(".vtm") assert isinstance(result["id"], str) assert re.match(r"[0-9a-f]{32}", result["id"]) assert isinstance(result["viewer_type"], str) @@ -207,10 +205,10 @@ def test_generate_native_viewable_and_light_viewable_from_file( ) assert isinstance(result, dict) - assert isinstance(result["native_filename"], str) - assert result["native_filename"].startswith("native.") - assert isinstance(result["viewable_filename"], str) - assert result["viewable_filename"].endswith(".vtm") + assert isinstance(result["native_file"], str) + assert result["native_file"].startswith("native.") + assert isinstance(result["viewable_file"], str) + assert result["viewable_file"].endswith(".vtm") assert isinstance(result["id"], str) assert re.match(r"[0-9a-f]{32}", result["id"]) assert isinstance(result["viewer_type"], str) From a192744a3d8f1a855364af3f7594e50a05be5151 Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Fri, 28 Nov 2025 16:27:21 +0100 Subject: [PATCH 19/21] typing --- src/opengeodeweb_back/utils_functions.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index 7099f54e..75c99bf0 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -5,6 +5,8 @@ import zipfile from collections.abc import Callable from concurrent.futures import ThreadPoolExecutor +from typing import Any + # Third party imports import flask @@ -101,7 +103,7 @@ def versions(list_packages: list[str]) -> list[dict[str, str]]: return list_with_versions -def validate_request(request: flask.Request, schema: SchemaDict) -> dict: +def validate_request(request: flask.Request, schema: SchemaDict) -> dict[str, Any]: json_data = request.get_json(force=True, silent=True) if json_data is None: @@ -209,10 +211,10 @@ def save_all_viewables_and_return_info( binary_light_viewable = f.read() data.native_file = os.path.basename(native_files[0]) data.viewable_file = os.path.basename(viewable_path) - data.light_viewable = os.path.basename(light_path) + data.light_viewable_file = os.path.basename(light_path) assert data.native_file is not None assert data.viewable_file is not None - assert data.light_viewable is not None + assert data.light_viewable_file is not None return { "native_file": data.native_file, "viewable_file": data.viewable_file, From 77d713c7f3b920600ce945b4d7ab8d546034bbda Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Mon, 1 Dec 2025 10:26:25 +0100 Subject: [PATCH 20/21] fix tests --- src/opengeodeweb_back/routes/create/blueprint_create.py | 4 ++-- tests/test_models_routes.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/opengeodeweb_back/routes/create/blueprint_create.py b/src/opengeodeweb_back/routes/create/blueprint_create.py index 2b49a83d..74c594ef 100644 --- a/src/opengeodeweb_back/routes/create/blueprint_create.py +++ b/src/opengeodeweb_back/routes/create/blueprint_create.py @@ -77,8 +77,8 @@ def create_aoi() -> flask.Response: ) def create_voi() -> flask.Response: """Endpoint to create a Volume of Interest (VOI) as an EdgedCurve3D (a bounding box/prism).""" - utils_functions.validate_request(flask.request, schemas_dict["create_voi"]) - params = schemas.CreateVoi.from_dict(flask.request.get_json()) + json_data = utils_functions.validate_request(flask.request, schemas_dict["create_voi"]) + params = schemas.CreateVoi.from_dict(json_data) aoi_data = geode_functions.get_data_info(params.aoi_id) if not aoi_data: diff --git a/tests/test_models_routes.py b/tests/test_models_routes.py index a4a2f571..379e5b16 100644 --- a/tests/test_models_routes.py +++ b/tests/test_models_routes.py @@ -107,7 +107,7 @@ def test_import_project_route(client: FlaskClient, tmp_path: Path) -> None: conn = sqlite3.connect(str(temp_db)) conn.execute( "CREATE TABLE datas (id TEXT PRIMARY KEY, geode_object TEXT, viewer_object TEXT, native_file TEXT, " - "viewable_file TEXT, light_viewable TEXT, input_file TEXT, additional_files TEXT)" + "viewable_file TEXT, light_viewable_file TEXT, input_file TEXT, additional_files TEXT)" ) conn.commit() conn.close() From c0b3880b75042188ef23a79517fa00e11ab88d17 Mon Sep 17 00:00:00 2001 From: JulienChampagnol <91873154+JulienChampagnol@users.noreply.github.com> Date: Mon, 1 Dec 2025 09:27:11 +0000 Subject: [PATCH 21/21] Apply prepare changes --- src/opengeodeweb_back/routes/create/blueprint_create.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/opengeodeweb_back/routes/create/blueprint_create.py b/src/opengeodeweb_back/routes/create/blueprint_create.py index 74c594ef..b788f261 100644 --- a/src/opengeodeweb_back/routes/create/blueprint_create.py +++ b/src/opengeodeweb_back/routes/create/blueprint_create.py @@ -77,7 +77,9 @@ def create_aoi() -> flask.Response: ) def create_voi() -> flask.Response: """Endpoint to create a Volume of Interest (VOI) as an EdgedCurve3D (a bounding box/prism).""" - json_data = utils_functions.validate_request(flask.request, schemas_dict["create_voi"]) + json_data = utils_functions.validate_request( + flask.request, schemas_dict["create_voi"] + ) params = schemas.CreateVoi.from_dict(json_data) aoi_data = geode_functions.get_data_info(params.aoi_id)