From c6f3a4fe2fd43dd241879811b91fbcd0299ad0c4 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Thu, 9 Jul 2026 01:28:24 +0200 Subject: [PATCH 01/11] feat(HorizonStack): Add Horizon Stack to the horizon step --- .../geode_objects/__init__.py | 2 + .../geode_objects/geode_horizon_stack3d.py | 108 ++++++++++++++++++ src/opengeodeweb_back/utils_functions.py | 21 ++-- 3 files changed, 123 insertions(+), 8 deletions(-) create mode 100644 src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py diff --git a/src/opengeodeweb_back/geode_objects/__init__.py b/src/opengeodeweb_back/geode_objects/__init__.py index d1329a1d..5eb46f65 100644 --- a/src/opengeodeweb_back/geode_objects/__init__.py +++ b/src/opengeodeweb_back/geode_objects/__init__.py @@ -31,6 +31,7 @@ from .geode_cross_section import GeodeCrossSection from .geode_implicit_structural_model import GeodeImplicitStructuralModel from .geode_implicit_cross_section import GeodeImplicitCrossSection +from .geode_horizon_stack3d import GeodeHorizonStack3D geode_objects: dict[GeodeObjectType, type[GeodeObject]] = { "VertexSet": GeodeVertexSet, @@ -58,4 +59,5 @@ "CrossSection": GeodeCrossSection, "ImplicitStructuralModel": GeodeImplicitStructuralModel, "ImplicitCrossSection": GeodeImplicitCrossSection, + "HorizonStack3D": GeodeHorizonStack3D, } diff --git a/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py new file mode 100644 index 00000000..0365c2c3 --- /dev/null +++ b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py @@ -0,0 +1,108 @@ +# Standard library imports +from __future__ import annotations + +# Third party imports +import opengeode as og +import opengeode_geosciences as og_geosciences +from opengeodeweb_microservice.database.data_types import GeodeModelType + +# Local application imports +from .geode_model import GeodeModel, ComponentRegistry + + +class GeodeHorizonStack3D(GeodeModel): + horizon_stack: og_geosciences.HorizonsStack3D + + def __init__(self, horizon_stack: og_geosciences.HorizonsStack3D | None = None) -> None: + self.horizon_stack = horizon_stack if horizon_stack is not None else og_geosciences.HorizonsStack3D() + super().__init__(self.horizon_stack) + + @classmethod + def geode_object_type(cls) -> GeodeModelType: + return "HorizonStack3D" + + def native_extension(self) -> str: + return self.horizon_stack.native_extension() + + @classmethod + def is_3D(cls) -> bool: + return True + + @classmethod + def is_viewable(cls) -> bool: + return False # Or True if there's a viewable output + + def builder(self) -> og_geosciences.HorizonsStackBuilder3D: + return og_geosciences.HorizonsStackBuilder3D(self.horizon_stack) + + @classmethod + def load(cls, filename: str) -> GeodeHorizonStack3D: + return GeodeHorizonStack3D(og_geosciences.load_horizons_stack3D(filename)) + + @classmethod + def additional_files(cls, filename: str) -> og.AdditionalFiles: + # Check if python binding for additional files exists, else return empty + if hasattr(og_geosciences, "horizons_stack_additional_files3D"): + return og_geosciences.horizons_stack_additional_files3D(filename) + return [] + + @classmethod + def is_loadable(cls, filename: str) -> og.Percentage: + if hasattr(og_geosciences, "is_horizons_stack_loadable3D"): + return og_geosciences.is_horizons_stack_loadable3D(filename) + return 0 + + @classmethod + def input_extensions(cls) -> list[str]: + if hasattr(og_geosciences, "HorizonsStackInputFactory3D"): + return og_geosciences.HorizonsStackInputFactory3D.list_creators() + return [] + + @classmethod + def output_extensions(cls) -> list[str]: + if hasattr(og_geosciences, "HorizonsStackOutputFactory3D"): + return og_geosciences.HorizonsStackOutputFactory3D.list_creators() + return [] + + @classmethod + def object_priority(cls, filename: str) -> int: + if hasattr(og_geosciences, "horizons_stack_object_priority3D"): + return og_geosciences.horizons_stack_object_priority3D(filename) + return 0 + + def is_saveable(self, filename: str) -> bool: + if hasattr(og_geosciences, "is_horizons_stack_saveable3D"): + return og_geosciences.is_horizons_stack_saveable3D(self.horizon_stack, filename) + return True + + def save(self, filename: str) -> list[str]: + if hasattr(og_geosciences, "save_horizons_stack3D"): + return og_geosciences.save_horizons_stack3D(self.horizon_stack, filename) + return [] + + def save_viewable(self, filename_without_extension: str) -> str: + return "" + + def save_light_viewable(self, filename_without_extension: str) -> str: + return "" + + def mesh_components(self) -> ComponentRegistry: + return {} + + def collection_components(self) -> ComponentRegistry: + return {} + + def boundaries(self, id: og.uuid) -> list[og.ComponentID]: + return [] + + def internals(self, id: og.uuid) -> list[og.ComponentID]: + return [] + + def items(self, id: og.uuid) -> list[og.ComponentID]: + return [] + + def component(self, id: og.uuid) -> og.Component3D: + return None # Needs proper implementation if HorizonsStack contains components + + def inspect(self) -> None: + return None diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index 34e5cf3b..8acdd531 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -286,15 +286,20 @@ def save_all_viewables_and_return_info( ), ], ) - with open(light_path, "rb") as f: - binary_light_viewable = f.read() + if geode_object.is_viewable(): + with open(light_path, "rb") as f: + binary_light_viewable = f.read() + binary_light_viewable_str = binary_light_viewable.decode("utf-8") + data.viewable_file = os.path.basename(viewable_path) + data.light_viewable_file = os.path.basename(light_path) + else: + binary_light_viewable_str = "" + data.viewable_file = "" + data.light_viewable_file = "" + data.native_file = os.path.basename(native_files[0]) - data.viewable_file = os.path.basename(viewable_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_file is not None name = geode_object.identifier.name() if not name: flask.abort(400, "Geode object has no name defined.") @@ -305,12 +310,12 @@ def save_all_viewables_and_return_info( "id": data.id, "name": name, "viewer_type": data.viewer_object, - "binary_light_viewable": binary_light_viewable.decode("utf-8"), + "binary_light_viewable": binary_light_viewable_str, "geode_object_type": data.geode_object, } if isinstance(geode_object, GeodeVertexSet): response["nb_vertices"] = geode_object.vertex_set.nb_vertices() - if isinstance(geode_object, GeodeModel): + if isinstance(geode_object, GeodeModel) and geode_object.is_viewable(): response |= model_components(data.id, geode_object, data.viewable_file) return response From 8b9dd98b95a125f15caddb2f0b11804e6586a48b Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Mon, 13 Jul 2026 15:34:05 +0200 Subject: [PATCH 02/11] fix utils functions --- src/opengeodeweb_back/utils_functions.py | 33 ++++++++++++------------ 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index 8acdd531..fa655c4d 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -270,22 +270,23 @@ def save_all_viewables_and_return_info( data_path: str, ) -> dict[str, Any]: with ThreadPoolExecutor() as executor: - native_files, viewable_path, light_path = executor.map( - lambda args: args[0](args[1]), - [ - ( - geode_object.save, - os.path.join( - data_path, "native." + geode_object.native_extension() - ), - ), + tasks = [ + ( + geode_object.save, + os.path.join(data_path, "native." + geode_object.native_extension()), + ) + ] + if geode_object.is_viewable(): + tasks.extend([ (geode_object.save_viewable, os.path.join(data_path, "viewable")), - ( - geode_object.save_light_viewable, - os.path.join(data_path, "light_viewable"), - ), - ], - ) + (geode_object.save_light_viewable, os.path.join(data_path, "light_viewable")), + ]) + + results = list(executor.map(lambda args: args[0](args[1]), tasks)) + native_files = results[0] + if geode_object.is_viewable(): + viewable_path = results[1] + light_path = results[2] if geode_object.is_viewable(): with open(light_path, "rb") as f: binary_light_viewable = f.read() @@ -293,7 +294,7 @@ def save_all_viewables_and_return_info( data.viewable_file = os.path.basename(viewable_path) data.light_viewable_file = os.path.basename(light_path) else: - binary_light_viewable_str = "" + binary_light_viewable_str = "not_viewable" data.viewable_file = "" data.light_viewable_file = "" From 7a98960a308fab6bca2284965648ee87a93dae68 Mon Sep 17 00:00:00 2001 From: SpliiT <106495600+SpliiT@users.noreply.github.com> Date: Mon, 13 Jul 2026 14:24:04 +0000 Subject: [PATCH 03/11] Apply prepare changes --- requirements.txt | 1 - .../geode_objects/geode_horizon_stack3d.py | 18 +++++++++++++----- src/opengeodeweb_back/utils_functions.py | 15 ++++++++++----- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/requirements.txt b/requirements.txt index d4529ea2..d1953d29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -66,4 +66,3 @@ werkzeug==3.1.8 # flask # flask-cors -opengeodeweb-microservice==1.*,>=1.1.4rc1 diff --git a/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py index 0365c2c3..e61d012f 100644 --- a/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py @@ -13,8 +13,14 @@ class GeodeHorizonStack3D(GeodeModel): horizon_stack: og_geosciences.HorizonsStack3D - def __init__(self, horizon_stack: og_geosciences.HorizonsStack3D | None = None) -> None: - self.horizon_stack = horizon_stack if horizon_stack is not None else og_geosciences.HorizonsStack3D() + def __init__( + self, horizon_stack: og_geosciences.HorizonsStack3D | None = None + ) -> None: + self.horizon_stack = ( + horizon_stack + if horizon_stack is not None + else og_geosciences.HorizonsStack3D() + ) super().__init__(self.horizon_stack) @classmethod @@ -30,7 +36,7 @@ def is_3D(cls) -> bool: @classmethod def is_viewable(cls) -> bool: - return False # Or True if there's a viewable output + return False # Or True if there's a viewable output def builder(self) -> og_geosciences.HorizonsStackBuilder3D: return og_geosciences.HorizonsStackBuilder3D(self.horizon_stack) @@ -72,7 +78,9 @@ def object_priority(cls, filename: str) -> int: def is_saveable(self, filename: str) -> bool: if hasattr(og_geosciences, "is_horizons_stack_saveable3D"): - return og_geosciences.is_horizons_stack_saveable3D(self.horizon_stack, filename) + return og_geosciences.is_horizons_stack_saveable3D( + self.horizon_stack, filename + ) return True def save(self, filename: str) -> list[str]: @@ -102,7 +110,7 @@ def items(self, id: og.uuid) -> list[og.ComponentID]: return [] def component(self, id: og.uuid) -> og.Component3D: - return None # Needs proper implementation if HorizonsStack contains components + return None # Needs proper implementation if HorizonsStack contains components def inspect(self) -> None: return None diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index fa655c4d..178c284b 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -277,11 +277,16 @@ def save_all_viewables_and_return_info( ) ] if geode_object.is_viewable(): - tasks.extend([ - (geode_object.save_viewable, os.path.join(data_path, "viewable")), - (geode_object.save_light_viewable, os.path.join(data_path, "light_viewable")), - ]) - + tasks.extend( + [ + (geode_object.save_viewable, os.path.join(data_path, "viewable")), + ( + geode_object.save_light_viewable, + os.path.join(data_path, "light_viewable"), + ), + ] + ) + results = list(executor.map(lambda args: args[0](args[1]), tasks)) native_files = results[0] if geode_object.is_viewable(): From 8b7ade0a17858b53d9a4468b19e4cd410d4927b2 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Mon, 13 Jul 2026 16:30:27 +0200 Subject: [PATCH 04/11] add missing test.og_hst3d --- tests/data/test.og_hst3d | Bin 0 -> 912 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/data/test.og_hst3d diff --git a/tests/data/test.og_hst3d b/tests/data/test.og_hst3d new file mode 100644 index 0000000000000000000000000000000000000000..f007de2e55ddec1bdc94d2d964852c6865fff6a5 GIT binary patch literal 912 zcmWIWW@Zs#;NW0j*wXwqh5-tS85tO)f$ZXvqQsKS^rFOqjLhWtqSPE9FF&t1BeS5G ziII`dzaTZwJvBci)g7dQk&y`unSq)a7?_wcQ&?oe5{ohulX6lWOG=6|lS)fco%3@G z^7B&jN<3YF>X{fA7=h{-897VyQc}}0^HNio80SYnvUyS1+5PU=+R7{bdJMv;De0-j z@rgzGKt=IosYNBJ6|71aCcA=EIf501fz?3F$EqD@Eh8Hf%&LyQhCg;M9)5bqz{n01 zKf10)|D2MMa5~@tHseSHzdZ8$qpsDE|)y45I0vaEVV$$}dYr1RR%ea6w{G zF(NpU^7C_`;ecHS0|P4~HzN}#BLfRpfHylw-NJjDL9qkE0a)Ws7#R3mK%AKZ4CTzU z%+w;dN4s{{?E1X0r~x$fV1RNQ1~e1f@X;XkggV2x6f+1tmoWc%vGG>_1R|Kmf>~ zJ;1<21P{7CWKV&@2BD7~=ucD!fWrcx0U*C44DbRP01Jr#Z&o&t3=0tc0MbpMKx6;_ DRM7Pm literal 0 HcmV?d00001 From 28cd18e4f681f8799c73fd29562011525c3ec96d Mon Sep 17 00:00:00 2001 From: SpliiT <106495600+SpliiT@users.noreply.github.com> Date: Mon, 13 Jul 2026 14:52:58 +0000 Subject: [PATCH 05/11] Apply prepare changes --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 26be316f..d1953d29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -66,4 +66,3 @@ werkzeug==3.1.8 # flask # flask-cors -opengeodeweb-microservice==1.*,>=1.1.4 From 21df80a1c4869e7a989dd04099dddb792f45678b Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Mon, 13 Jul 2026 17:09:50 +0200 Subject: [PATCH 06/11] resolve mypy errors on GeodeHorizonStack3D and utils --- .../geode_objects/geode_horizon_stack3d.py | 16 ++++++++++------ src/opengeodeweb_back/utils_functions.py | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py index e61d012f..40b916bd 100644 --- a/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py @@ -1,5 +1,6 @@ # Standard library imports from __future__ import annotations +from typing import Any # Third party imports import opengeode as og @@ -50,13 +51,13 @@ def additional_files(cls, filename: str) -> og.AdditionalFiles: # Check if python binding for additional files exists, else return empty if hasattr(og_geosciences, "horizons_stack_additional_files3D"): return og_geosciences.horizons_stack_additional_files3D(filename) - return [] + return [] # type: ignore @classmethod def is_loadable(cls, filename: str) -> og.Percentage: if hasattr(og_geosciences, "is_horizons_stack_loadable3D"): return og_geosciences.is_horizons_stack_loadable3D(filename) - return 0 + return 0 # type: ignore @classmethod def input_extensions(cls) -> list[str]: @@ -78,9 +79,9 @@ def object_priority(cls, filename: str) -> int: def is_saveable(self, filename: str) -> bool: if hasattr(og_geosciences, "is_horizons_stack_saveable3D"): - return og_geosciences.is_horizons_stack_saveable3D( + return bool(og_geosciences.is_horizons_stack_saveable3D( self.horizon_stack, filename - ) + )) return True def save(self, filename: str) -> list[str]: @@ -110,7 +111,10 @@ def items(self, id: og.uuid) -> list[og.ComponentID]: return [] def component(self, id: og.uuid) -> og.Component3D: - return None # Needs proper implementation if HorizonsStack contains components + return None # type: ignore + + def inspect(self) -> Any: + return None - def inspect(self) -> None: + def validate(self) -> Any: return None diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index 178c284b..5b86097d 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -270,7 +270,7 @@ def save_all_viewables_and_return_info( data_path: str, ) -> dict[str, Any]: with ThreadPoolExecutor() as executor: - tasks = [ + tasks: list[tuple[Callable[[str], Any], str]] = [ ( geode_object.save, os.path.join(data_path, "native." + geode_object.native_extension()), From c75f16c395165bd1d7ca4fbbcf9e8e035d88edd6 Mon Sep 17 00:00:00 2001 From: SpliiT <106495600+SpliiT@users.noreply.github.com> Date: Mon, 13 Jul 2026 15:10:34 +0000 Subject: [PATCH 07/11] Apply prepare changes --- .../geode_objects/geode_horizon_stack3d.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py index 40b916bd..d1f3aed3 100644 --- a/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py @@ -79,9 +79,11 @@ def object_priority(cls, filename: str) -> int: def is_saveable(self, filename: str) -> bool: if hasattr(og_geosciences, "is_horizons_stack_saveable3D"): - return bool(og_geosciences.is_horizons_stack_saveable3D( - self.horizon_stack, filename - )) + return bool( + og_geosciences.is_horizons_stack_saveable3D( + self.horizon_stack, filename + ) + ) return True def save(self, filename: str) -> list[str]: From c9f3d0b5bb1693805d8019b0a69018811c2268fd Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Wed, 15 Jul 2026 11:36:40 +0200 Subject: [PATCH 08/11] rm comments --- src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py index 40b916bd..613805ff 100644 --- a/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py @@ -37,8 +37,7 @@ def is_3D(cls) -> bool: @classmethod def is_viewable(cls) -> bool: - return False # Or True if there's a viewable output - + return False def builder(self) -> og_geosciences.HorizonsStackBuilder3D: return og_geosciences.HorizonsStackBuilder3D(self.horizon_stack) @@ -48,7 +47,6 @@ def load(cls, filename: str) -> GeodeHorizonStack3D: @classmethod def additional_files(cls, filename: str) -> og.AdditionalFiles: - # Check if python binding for additional files exists, else return empty if hasattr(og_geosciences, "horizons_stack_additional_files3D"): return og_geosciences.horizons_stack_additional_files3D(filename) return [] # type: ignore From 7f9b1d280826059e720f917c11db72106d0dc43b Mon Sep 17 00:00:00 2001 From: SpliiT <106495600+SpliiT@users.noreply.github.com> Date: Wed, 15 Jul 2026 09:37:28 +0000 Subject: [PATCH 09/11] Apply prepare changes --- src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py index 93d23642..793821b2 100644 --- a/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py @@ -37,7 +37,8 @@ def is_3D(cls) -> bool: @classmethod def is_viewable(cls) -> bool: - return False + return False + def builder(self) -> og_geosciences.HorizonsStackBuilder3D: return og_geosciences.HorizonsStackBuilder3D(self.horizon_stack) From 2a0ecbd6f48a07fd2224029c392edae488d535d9 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Wed, 15 Jul 2026 14:04:32 +0200 Subject: [PATCH 10/11] fix comments --- .../geode_objects/geode_horizon_stack3d.py | 10 ++----- src/opengeodeweb_back/utils_functions.py | 29 ++++++++++--------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py index 93d23642..e6c9e6d9 100644 --- a/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py +++ b/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py @@ -47,15 +47,11 @@ def load(cls, filename: str) -> GeodeHorizonStack3D: @classmethod def additional_files(cls, filename: str) -> og.AdditionalFiles: - if hasattr(og_geosciences, "horizons_stack_additional_files3D"): - return og_geosciences.horizons_stack_additional_files3D(filename) - return [] # type: ignore + return og_geosciences.horizons_stack_additional_files3D(filename) @classmethod def is_loadable(cls, filename: str) -> og.Percentage: - if hasattr(og_geosciences, "is_horizons_stack_loadable3D"): - return og_geosciences.is_horizons_stack_loadable3D(filename) - return 0 # type: ignore + return og_geosciences.is_horizons_stack_loadable3D(filename) @classmethod def input_extensions(cls) -> list[str]: @@ -111,7 +107,7 @@ def items(self, id: og.uuid) -> list[og.ComponentID]: return [] def component(self, id: og.uuid) -> og.Component3D: - return None # type: ignore + raise NotImplementedError("HorizonStack3D has no mesh components") def inspect(self) -> Any: return None diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index 5b86097d..5627167b 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -200,18 +200,20 @@ def create_data_folder_from_id(data_id: str) -> str: def model_components( data_id: str, model: GeodeModel, viewable_file: str ) -> dict[str, Any]: - vtm_file_path = geode_functions.data_file_path(data_id, viewable_file) - tree = ET.parse(vtm_file_path) - root = tree.find("vtkMultiBlockDataSet") - if root is None: - flask.abort(500, "Failed to read viewable file") - uuid_to_flat_index = {} - current_index = 0 - assert root is not None - for elem in root.iter(): - if "uuid" in elem.attrib and elem.tag == "DataSet": - uuid_to_flat_index[elem.attrib["uuid"]] = current_index - current_index += 1 + uuid_to_flat_index: dict[str, int] = {} + if viewable_file: + vtm_file_path = geode_functions.data_file_path(data_id, viewable_file) + tree = ET.parse(vtm_file_path) + root = tree.find("vtkMultiBlockDataSet") + if root is None: + flask.abort(500, "Failed to read viewable file") + current_index = 0 + assert root is not None + for elem in root.iter(): + if "uuid" in elem.attrib and elem.tag == "DataSet": + uuid_to_flat_index[elem.attrib["uuid"]] = current_index + current_index += 1 + model_mesh_components = model.mesh_components() mesh_components = [] for mesh_component, ids in model_mesh_components.items(): @@ -292,7 +294,6 @@ def save_all_viewables_and_return_info( if geode_object.is_viewable(): viewable_path = results[1] light_path = results[2] - if geode_object.is_viewable(): with open(light_path, "rb") as f: binary_light_viewable = f.read() binary_light_viewable_str = binary_light_viewable.decode("utf-8") @@ -321,7 +322,7 @@ def save_all_viewables_and_return_info( } if isinstance(geode_object, GeodeVertexSet): response["nb_vertices"] = geode_object.vertex_set.nb_vertices() - if isinstance(geode_object, GeodeModel) and geode_object.is_viewable(): + if isinstance(geode_object, GeodeModel): response |= model_components(data.id, geode_object, data.viewable_file) return response From 6785a86f206eeeeeb0eb96ce492c254c8d4299b1 Mon Sep 17 00:00:00 2001 From: Tao Schiro Date: Fri, 17 Jul 2026 16:42:59 +0200 Subject: [PATCH 11/11] reput asserts data --- src/opengeodeweb_back/utils_functions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index 5627167b..de067853 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -307,6 +307,8 @@ def save_all_viewables_and_return_info( data.native_file = os.path.basename(native_files[0]) assert data.native_file is not None + assert data.viewable_file is not None + assert data.light_viewable_file is not None name = geode_object.identifier.name() if not name: flask.abort(400, "Geode object has no name defined.")