Skip to content

Commit fb40642

Browse files
Merge branch 'next' of https://github.com/Geode-solutions/OpenGeodeWeb-Back into feat/extensions_config
2 parents 4d4f24a + e41dd9f commit fb40642

19 files changed

Lines changed: 297 additions & 129 deletions

opengeodeweb_back_schemas.json

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333
}
3434
},
3535
"models": {
36-
"mesh_components": {
37-
"$id": "opengeodeweb_back/models/mesh_components",
38-
"route": "/mesh_components",
36+
"model_components": {
37+
"$id": "opengeodeweb_back/models/model_components",
38+
"route": "/model_components",
3939
"methods": [
4040
"POST"
4141
],
@@ -294,6 +294,24 @@
294294
],
295295
"additionalProperties": false
296296
},
297+
"geode_object_inheritance": {
298+
"$id": "opengeodeweb_back/geode_object_inheritance",
299+
"route": "/geode_object_inheritance",
300+
"methods": [
301+
"POST"
302+
],
303+
"type": "object",
304+
"properties": {
305+
"geode_object_type": {
306+
"type": "string",
307+
"minLength": 1
308+
}
309+
},
310+
"required": [
311+
"geode_object_type"
312+
],
313+
"additionalProperties": false
314+
},
297315
"export_project": {
298316
"$id": "opengeodeweb_back/export_project",
299317
"route": "/export_project",

requirements.in

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
opengeode-core==15.31.1
1+
opengeode-core==15.31.5
22
opengeode-io==7.4.8
3-
opengeode-inspector==6.8.16
4-
opengeode-geosciences==9.5.8
5-
opengeode-geosciencesio==5.8.9
6-
geode-common==33.18.0
3+
opengeode-inspector==6.8.17
4+
opengeode-geosciences==9.5.9
5+
opengeode-geosciencesio==5.8.10
6+
geode-common==33.19.0
77
geode-viewables==3.3.4
88
flask[async]==3.1.2
99
flask-cors==6.0.1

requirements.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ flask[async]>=3
1616
# flask-cors
1717
flask-cors==6.0.1
1818
# via -r requirements.in
19-
geode-common==33.18.0
19+
geode-common==33.19.0
2020
# via
2121
# -r requirements.in
2222
# geode-viewables
@@ -31,7 +31,7 @@ markupsafe>=3
3131
# flask
3232
# jinja2
3333
# werkzeug
34-
opengeode-core==15.31.1
34+
opengeode-core==15.31.5
3535
# via
3636
# -r requirements.in
3737
# geode-common
@@ -40,14 +40,14 @@ opengeode-core==15.31.1
4040
# opengeode-geosciencesio
4141
# opengeode-inspector
4242
# opengeode-io
43-
opengeode-geosciences==9.5.8
43+
opengeode-geosciences==9.5.9
4444
# via
4545
# -r requirements.in
4646
# geode-viewables
4747
# opengeode-geosciencesio
48-
opengeode-geosciencesio==5.8.9
48+
opengeode-geosciencesio==5.8.10
4949
# via -r requirements.in
50-
opengeode-inspector==6.8.16
50+
opengeode-inspector==6.8.17
5151
# via -r requirements.in
5252
opengeode-io==7.4.8
5353
# via
@@ -60,4 +60,4 @@ werkzeug==3.1.2
6060
# flask
6161
# flask-cors
6262

63-
opengeodeweb-microservice==1.*,>=1.0.14
63+
opengeodeweb-microservice==1.*,>=1.0.15rc1

src/opengeodeweb_back/geode_objects/geode_brep.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,18 @@ def save_light_viewable(self, filename_without_extension: str) -> str:
7676
def mesh_components(self) -> ComponentRegistry:
7777
return self.brep.mesh_components()
7878

79+
def collection_components(self) -> ComponentRegistry:
80+
return self.brep.collection_components()
81+
82+
def boundaries(self, id: og.uuid) -> list[og.ComponentID]:
83+
return self.brep.boundaries(id)
84+
85+
def internals(self, id: og.uuid) -> list[og.ComponentID]:
86+
return self.brep.internals(id)
87+
88+
def items(self, id: og.uuid) -> list[og.ComponentID]:
89+
return self.brep.items(id)
90+
7991
def inspect(self) -> og_inspector.BRepInspectionResult:
8092
return og_inspector.inspect_brep(self.brep)
8193

src/opengeodeweb_back/geode_objects/geode_model.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,15 @@ def viewer_elements_type(cls) -> ViewerElementsType:
2323

2424
@abstractmethod
2525
def mesh_components(self) -> ComponentRegistry: ...
26+
27+
@abstractmethod
28+
def collection_components(self) -> ComponentRegistry: ...
29+
30+
@abstractmethod
31+
def boundaries(self, id: og.uuid) -> list[og.ComponentID]: ...
32+
33+
@abstractmethod
34+
def internals(self, id: og.uuid) -> list[og.ComponentID]: ...
35+
36+
@abstractmethod
37+
def items(self, id: og.uuid) -> list[og.ComponentID]: ...

src/opengeodeweb_back/geode_objects/geode_section.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@ def save_light_viewable(self, filename_without_extension: str) -> str:
7878
def mesh_components(self) -> ComponentRegistry:
7979
return self.section.mesh_components()
8080

81+
def collection_components(self) -> ComponentRegistry:
82+
return self.section.collection_components()
83+
84+
def boundaries(self, id: og.uuid) -> list[og.ComponentID]:
85+
return self.section.boundaries(id)
86+
87+
def internals(self, id: og.uuid) -> list[og.ComponentID]:
88+
return self.section.internals(id)
89+
90+
def items(self, id: og.uuid) -> list[og.ComponentID]:
91+
return self.section.items(id)
92+
8193
def inspect(self) -> og_inspector.SectionInspectionResult:
8294
return og_inspector.inspect_section(self.section)
8395

src/opengeodeweb_back/routes/blueprint_routes.py

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ def ping() -> flask.Response:
402402
@routes.route(schemas_dict["kill"]["route"], methods=schemas_dict["kill"]["methods"])
403403
def kill() -> flask.Response:
404404
print("Manual server kill, shutting down...", flush=True)
405+
utils_functions.teardown_request(flask.current_app)
405406
os._exit(0)
406407
return flask.make_response({"message": "Flask server is dead"}, 200)
407408

@@ -425,7 +426,7 @@ def export_project() -> flask.Response:
425426
export_vease_path = os.path.join(project_folder, filename)
426427

427428
with get_session() as session:
428-
rows = session.query(Data.id, Data.input_file, Data.additional_files).all()
429+
rows = session.query(Data.id, Data.native_file).all()
429430

430431
with zipfile.ZipFile(
431432
export_vease_path, "w", compression=zipfile.ZIP_DEFLATED
@@ -434,21 +435,12 @@ def export_project() -> flask.Response:
434435
if os.path.isfile(database_root_path):
435436
zip_file.write(database_root_path, "project.db")
436437

437-
for data_id, input_file, additional_files in rows:
438+
for data_id, native_file in rows:
438439
base_dir = os.path.join(project_folder, data_id)
439440

440-
input_path = os.path.join(base_dir, str(input_file))
441-
if os.path.isfile(input_path):
442-
zip_file.write(input_path, os.path.join(data_id, str(input_file)))
443-
444-
for relative_path in (
445-
additional_files if isinstance(additional_files, list) else []
446-
):
447-
additional_path = os.path.join(base_dir, relative_path)
448-
if os.path.isfile(additional_path):
449-
zip_file.write(
450-
additional_path, os.path.join(data_id, relative_path)
451-
)
441+
native_path = os.path.join(base_dir, str(native_file))
442+
if os.path.isfile(native_path):
443+
zip_file.write(native_path, os.path.join(data_id, str(native_file)))
452444

453445
zip_file.writestr("snapshot.json", flask.json.dumps(params.snapshot))
454446

@@ -523,17 +515,17 @@ def import_project() -> flask.Response:
523515
if os.path.isfile(vpath):
524516
continue
525517

526-
input_file = str(data.input_file or "")
527-
if not input_file:
518+
native_file = str(data.native_file or "")
519+
if not native_file:
528520
continue
529521

530-
input_full = geode_functions.data_file_path(data.id, input_file)
531-
if not os.path.isfile(input_full):
522+
native_full = geode_functions.data_file_path(data.id, native_file)
523+
if not os.path.isfile(native_full):
532524
continue
533525

534526
geode_object = geode_functions.geode_object_from_string(
535527
data.geode_object
536-
).load(input_full)
528+
).load(native_full)
537529
utils_functions.save_all_viewables_and_return_info(
538530
geode_object, data, data_path
539531
)
@@ -546,3 +538,48 @@ def import_project() -> flask.Response:
546538
except KeyError:
547539
snapshot = {}
548540
return flask.make_response({"snapshot": snapshot}, 200)
541+
542+
543+
@routes.route(
544+
schemas_dict["geode_object_inheritance"]["route"],
545+
methods=schemas_dict["geode_object_inheritance"]["methods"],
546+
)
547+
def geode_object_inheritance() -> flask.Response:
548+
json_data = utils_functions.validate_request(
549+
flask.request, schemas_dict["geode_object_inheritance"]
550+
)
551+
params = schemas.GeodeObjectInheritance.from_dict(json_data)
552+
geode_object_type = params.geode_object_type
553+
target_class = geode_functions.geode_object_from_string(geode_object_type)
554+
555+
def get_all_bases(geode_class: type) -> set[type]:
556+
bases = set()
557+
for base_class in geode_class.__bases__:
558+
if base_class is not object:
559+
bases.add(base_class)
560+
bases.update(get_all_bases(base_class))
561+
return bases
562+
563+
def get_all_subclasses(geode_class: type) -> set[type]:
564+
subclasses = set()
565+
for subclass_class in geode_class.__subclasses__():
566+
subclasses.add(subclass_class)
567+
subclasses.update(get_all_subclasses(subclass_class))
568+
return subclasses
569+
570+
# Extract all related Geode classes (parents and children)
571+
base_classes = get_all_bases(target_class)
572+
subclass_classes = get_all_subclasses(target_class)
573+
574+
# Filter GeodeObjectType to only include registered related objects, excluding target
575+
parents = []
576+
children = []
577+
for geode_object_type_str, geode_class in geode_objects.items():
578+
if geode_class == target_class:
579+
continue
580+
if geode_class in base_classes:
581+
parents.append(geode_object_type_str)
582+
if geode_class in subclass_classes:
583+
children.append(geode_object_type_str)
584+
585+
return flask.make_response({"parents": parents, "children": children}, 200)

src/opengeodeweb_back/routes/models/blueprint_models.py

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212

1313

1414
@routes.route(
15-
schemas_dict["mesh_components"]["route"],
16-
methods=schemas_dict["mesh_components"]["methods"],
15+
schemas_dict["model_components"]["route"],
16+
methods=schemas_dict["model_components"]["methods"],
1717
)
18-
def mesh_components() -> flask.Response:
18+
def model_components() -> flask.Response:
1919
json_data = utils_functions.validate_request(
20-
flask.request, schemas_dict["mesh_components"]
20+
flask.request, schemas_dict["model_components"]
2121
)
22-
params = schemas.MeshComponents.from_dict(json_data)
22+
params = schemas.ModelComponents.from_dict(json_data)
2323
model = geode_functions.load_geode_object(params.id)
2424
if not isinstance(model, GeodeModel):
2525
flask.abort(400, f"{params.id} is not a GeodeModel")
@@ -44,14 +44,40 @@ def mesh_components() -> flask.Response:
4444
geode_id = id.string()
4545
component_name = geode_id
4646
viewer_id = uuid_to_flat_index[geode_id]
47-
47+
boundaries = model.boundaries(id)
48+
boundaries_uuid = [boundary.id().string() for boundary in boundaries]
49+
internals = model.internals(id)
50+
internals_uuid = [internal.id().string() for internal in internals]
4851
mesh_component_object = {
49-
"id": params.id,
5052
"viewer_id": viewer_id,
5153
"geode_id": geode_id,
5254
"name": component_name,
5355
"type": component_type,
56+
"boundaries": boundaries_uuid,
57+
"internals": internals_uuid,
5458
}
5559
mesh_components.append(mesh_component_object)
5660

57-
return flask.make_response({"mesh_components": mesh_components}, 200)
61+
model_collection_components = model.collection_components()
62+
collection_components = []
63+
for collection_component, ids in model_collection_components.items():
64+
component_type = collection_component.get()
65+
for id in ids:
66+
geode_id = id.string()
67+
items = model.items(id)
68+
items_uuid = [item.id().string() for item in items]
69+
collection_component_object = {
70+
"geode_id": geode_id,
71+
"name": geode_id,
72+
"type": component_type,
73+
"items": items_uuid,
74+
}
75+
collection_components.append(collection_component_object)
76+
77+
return flask.make_response(
78+
{
79+
"mesh_components": mesh_components,
80+
"collection_components": collection_components,
81+
},
82+
200,
83+
)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from .mesh_components import *
1+
from .model_components import *

src/opengeodeweb_back/routes/models/schemas/mesh_components.json renamed to src/opengeodeweb_back/routes/models/schemas/model_components.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"route": "/mesh_components",
2+
"route": "/model_components",
33
"methods": [
44
"POST"
55
],

0 commit comments

Comments
 (0)