Skip to content

Commit bbebf18

Browse files
authored
Merge pull request #129 from Geode-solutions/feat_model_blueprint
Feat model blueprint
2 parents b5e9036 + bbffdbd commit bbebf18

File tree

9 files changed

+207
-10
lines changed

9 files changed

+207
-10
lines changed

app.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from werkzeug.exceptions import HTTPException
88

99
from src.opengeodeweb_back.routes import blueprint_routes
10+
from src.opengeodeweb_back.routes.models import blueprint_models
1011
from src.opengeodeweb_back.utils_functions import handle_exception
1112
from src.opengeodeweb_back import app_config
1213

@@ -34,6 +35,12 @@
3435
name="blueprint_routes",
3536
)
3637

38+
app.register_blueprint(
39+
blueprint_models.routes,
40+
url_prefix="/models",
41+
name="blueprint_models",
42+
)
43+
3744

3845
@app.errorhandler(HTTPException)
3946
def errorhandler(e):

requirements.txt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ flask[async]==3.1.0
2020
# flask-cors
2121
flask-cors==5.0.1
2222
# via -r requirements.in
23-
geode-background==9.1.5
23+
geode-background==9.2.0
2424
# via
2525
# geode-explicit
2626
# geode-implicit
2727
# geode-simplex
28-
geode-common==33.7.2
28+
geode-common==33.7.5
2929
# via
3030
# -r requirements.in
3131
# geode-background
@@ -35,27 +35,27 @@ geode-common==33.7.2
3535
# geode-numerics
3636
# geode-simplex
3737
# geode-viewables
38-
geode-conversion==6.2.7
38+
geode-conversion==6.2.9
3939
# via
4040
# geode-explicit
4141
# geode-implicit
4242
# geode-simplex
43-
geode-explicit==6.1.35
43+
geode-explicit==6.1.37
4444
# via
4545
# -r requirements.in
4646
# geode-implicit
47-
geode-implicit==3.7.4
47+
geode-implicit==3.7.6
4848
# via -r requirements.in
4949
geode-numerics==6.0.3
5050
# via
5151
# -r requirements.in
5252
# geode-implicit
5353
# geode-simplex
54-
geode-simplex==9.2.5
54+
geode-simplex==9.2.6
5555
# via
5656
# -r requirements.in
5757
# geode-implicit
58-
geode-viewables==3.0.12
58+
geode-viewables==3.1.0
5959
# via -r requirements.in
6060
itsdangerous==2.2.0
6161
# via flask
@@ -69,7 +69,7 @@ markupsafe==3.0.2
6969
# via
7070
# jinja2
7171
# werkzeug
72-
opengeode-core==15.17.8
72+
opengeode-core==15.17.12
7373
# via
7474
# -r requirements.in
7575
# geode-background
@@ -84,7 +84,7 @@ opengeode-core==15.17.8
8484
# opengeode-geosciencesio
8585
# opengeode-inspector
8686
# opengeode-io
87-
opengeode-geosciences==8.4.3
87+
opengeode-geosciences==8.4.4
8888
# via
8989
# -r requirements.in
9090
# geode-implicit

src/opengeodeweb_back/routes/blueprint_routes.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
# Local application imports
1313
from .. import geode_functions, utils_functions
1414

15-
routes = flask.Blueprint("routes", __name__)
15+
from .models import blueprint_models
16+
17+
routes = flask.Blueprint("routes", __name__, url_prefix="/opengeodeweb_back")
1618

1719

1820
@routes.before_request
@@ -23,11 +25,19 @@ def before_request():
2325

2426
@routes.teardown_request
2527
def teardown_request(exception):
28+
2629
if "ping" not in flask.request.path:
2730
utils_functions.decrement_request_counter(flask.current_app)
2831
utils_functions.update_last_request_time(flask.current_app)
2932

3033

34+
routes.register_blueprint(
35+
blueprint_models.routes,
36+
url_prefix=blueprint_models.routes.url_prefix,
37+
name=blueprint_models.routes.name,
38+
)
39+
40+
3141
schemas = os.path.join(os.path.dirname(__file__), "schemas")
3242

3343
with open(
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import json
2+
import os
3+
import xml.etree.ElementTree as ET
4+
import flask
5+
from ... import geode_functions, utils_functions
6+
7+
routes = flask.Blueprint("models", __name__, url_prefix="/models")
8+
9+
10+
schemas = os.path.join(os.path.dirname(__file__), "schemas")
11+
12+
with open(os.path.join(schemas, "vtm_component_indices.json"), "r") as file:
13+
vtm_component_indices_json = json.load(file)
14+
15+
16+
@routes.route(
17+
vtm_component_indices_json["route"], methods=vtm_component_indices_json["methods"]
18+
)
19+
def uuid_to_flat_index():
20+
21+
print(f"uuid_to_flat_index : {flask.request=}", flush=True)
22+
utils_functions.validate_request(flask.request, vtm_component_indices_json)
23+
vtm_file_path = os.path.join(
24+
flask.current_app.config["DATA_FOLDER_PATH"], flask.request.json["id"] + ".vtm"
25+
)
26+
27+
tree = ET.parse(vtm_file_path)
28+
root = tree.getroot()
29+
uuid_to_flat_index = {}
30+
current_index = 1
31+
32+
for elem in root.iter():
33+
if "uuid" in elem.attrib and elem.tag == "DataSet":
34+
uuid_to_flat_index[elem.attrib["uuid"]] = current_index
35+
current_index += 1
36+
37+
return flask.make_response(
38+
{"uuid_to_flat_index": uuid_to_flat_index},
39+
200,
40+
)
41+
42+
43+
def extract_model_uuids(geode_object, file_path):
44+
model = geode_functions.load(geode_object, file_path)
45+
mesh_components = model.mesh_components()
46+
47+
uuid_dict = {}
48+
49+
for mesh_component, ids in mesh_components.items():
50+
component_name = mesh_component.get()
51+
uuid_dict[component_name] = [id.string() for id in ids]
52+
53+
return uuid_dict
54+
55+
56+
with open(os.path.join(schemas, "mesh_components.json"), "r") as file:
57+
mesh_components_json = json.load(file)
58+
59+
60+
@routes.route(mesh_components_json["route"], methods=mesh_components_json["methods"])
61+
def extract_uuids_endpoint():
62+
print(f"extract_uuids_endpoint : {flask.request=}", flush=True)
63+
64+
utils_functions.validate_request(flask.request, mesh_components_json)
65+
66+
file_path = os.path.join(
67+
flask.current_app.config["DATA_FOLDER_PATH"], flask.request.json["filename"]
68+
)
69+
70+
if not os.path.exists(file_path):
71+
return flask.make_response({"error": "File not found"}, 404)
72+
73+
uuid_dict = extract_model_uuids(flask.request.json["geode_object"], file_path)
74+
return flask.make_response({"uuid_dict": uuid_dict}, 200)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"route": "/mesh_components",
3+
"methods": [
4+
"POST"
5+
],
6+
"type": "object",
7+
"properties": {
8+
"filename": {
9+
"type": "string"
10+
},
11+
"geode_object": {
12+
"type": "string"
13+
}
14+
},
15+
"required": [
16+
"filename",
17+
"geode_object"
18+
],
19+
"additionalProperties": false
20+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"route": "/vtm_component_indices",
3+
"methods": [
4+
"POST"
5+
],
6+
"type": "object",
7+
"properties": {
8+
"id": {
9+
"type": "string"
10+
}
11+
},
12+
"required": [
13+
"id"
14+
],
15+
"additionalProperties": false
16+
}

tests/data/cube.og_brep

463 KB
Binary file not shown.

tests/data/cube.vtm

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?xml version="1.0"?>
2+
<VTKFile type="vtkMultiBlockDataSet" version="1.0" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
3+
<vtkMultiBlockDataSet>
4+
<Block name="corners" index="0">
5+
<DataSet index="0" name="default_name" uuid="00000000-3bf3-4551-8000-000064de2fdd" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Corner_00000000-3bf3-4551-8000-000064de2fdd.vtp" />
6+
<DataSet index="1" name="default_name" uuid="00000000-4629-412b-8000-0000edfff497" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Corner_00000000-4629-412b-8000-0000edfff497.vtp" />
7+
<DataSet index="2" name="default_name" uuid="00000000-7dc7-495b-8000-000052017dae" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Corner_00000000-7dc7-495b-8000-000052017dae.vtp" />
8+
<DataSet index="3" name="default_name" uuid="00000000-8a73-4f55-8000-00002bf05d8e" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Corner_00000000-8a73-4f55-8000-00002bf05d8e.vtp" />
9+
<DataSet index="4" name="default_name" uuid="00000000-96bd-4157-8000-0000213ddb29" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Corner_00000000-96bd-4157-8000-0000213ddb29.vtp" />
10+
<DataSet index="5" name="default_name" uuid="00000000-ecd6-40de-8000-0000f7ed1e32" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Corner_00000000-ecd6-40de-8000-0000f7ed1e32.vtp" />
11+
<DataSet index="6" name="default_name" uuid="00000000-f9e9-4ddd-8000-0000f19cf8cb" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Corner_00000000-f9e9-4ddd-8000-0000f19cf8cb.vtp" />
12+
<DataSet index="7" name="default_name" uuid="00000000-fc1e-4e5f-8000-00000af3f679" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Corner_00000000-fc1e-4e5f-8000-00000af3f679.vtp" />
13+
</Block>
14+
<Block name="lines" index="1">
15+
<DataSet index="0" name="default_name" uuid="00000000-15ab-453c-8000-0000beee33c6" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Line_00000000-15ab-453c-8000-0000beee33c6.vtp" />
16+
<DataSet index="1" name="default_name" uuid="00000000-1bd9-41e4-8000-000055e171a2" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Line_00000000-1bd9-41e4-8000-000055e171a2.vtp" />
17+
<DataSet index="2" name="default_name" uuid="00000000-2326-4c21-8000-000054a373c7" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Line_00000000-2326-4c21-8000-000054a373c7.vtp" />
18+
<DataSet index="3" name="default_name" uuid="00000000-304e-44a7-8000-0000c72260c1" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Line_00000000-304e-44a7-8000-0000c72260c1.vtp" />
19+
<DataSet index="4" name="default_name" uuid="00000000-4755-4dfa-8000-000055999885" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Line_00000000-4755-4dfa-8000-000055999885.vtp" />
20+
<DataSet index="5" name="default_name" uuid="00000000-57cf-41f4-8000-00006a4349dc" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Line_00000000-57cf-41f4-8000-00006a4349dc.vtp" />
21+
<DataSet index="6" name="default_name" uuid="00000000-5a6b-45b2-8000-000004be554e" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Line_00000000-5a6b-45b2-8000-000004be554e.vtp" />
22+
<DataSet index="7" name="default_name" uuid="00000000-93f2-437a-8000-00001b2727be" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Line_00000000-93f2-437a-8000-00001b2727be.vtp" />
23+
<DataSet index="8" name="default_name" uuid="00000000-98f6-4012-8000-0000eb927a96" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Line_00000000-98f6-4012-8000-0000eb927a96.vtp" />
24+
<DataSet index="9" name="default_name" uuid="00000000-9ca0-4e51-8000-00005b81d027" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Line_00000000-9ca0-4e51-8000-00005b81d027.vtp" />
25+
<DataSet index="10" name="default_name" uuid="00000000-d720-47c9-8000-0000e54053cc" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Line_00000000-d720-47c9-8000-0000e54053cc.vtp" />
26+
<DataSet index="11" name="default_name" uuid="00000000-f3ec-4765-8000-0000d74e506d" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Line_00000000-f3ec-4765-8000-0000d74e506d.vtp" />
27+
</Block>
28+
<Block name="surfaces" index="2">
29+
<DataSet index="0" name="default_name" uuid="00000000-1702-4d26-8000-000004d7ea39" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Surface_00000000-1702-4d26-8000-000004d7ea39.vtp" />
30+
<DataSet index="1" name="default_name" uuid="00000000-6732-4f29-8000-00002f66bc93" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Surface_00000000-6732-4f29-8000-00002f66bc93.vtp" />
31+
<DataSet index="2" name="default_name" uuid="00000000-8afd-4969-8000-000092a43747" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Surface_00000000-8afd-4969-8000-000092a43747.vtp" />
32+
<DataSet index="3" name="default_name" uuid="00000000-cddf-4c1c-8000-00005ebbcaeb" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Surface_00000000-cddf-4c1c-8000-00005ebbcaeb.vtp" />
33+
<DataSet index="4" name="default_name" uuid="00000000-dc1c-420d-8000-000070dcfff5" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Surface_00000000-dc1c-420d-8000-000070dcfff5.vtp" />
34+
<DataSet index="5" name="default_name" uuid="00000000-dcfe-400a-8000-0000a72c4f30" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Surface_00000000-dcfe-400a-8000-0000a72c4f30.vtp" />
35+
</Block>
36+
<Block name="blocks" index="3">
37+
<DataSet index="0" file="b11b028cbe4c4e7c9d27279e52ea5eb2/Block_00000000-4335-411d-8000-000079b34fe5.vtu" name="default_name" uuid="00000000-4335-411d-8000-000079b34fe5" />
38+
</Block>
39+
</vtkMultiBlockDataSet>
40+
</VTKFile>

tests/test_models_routes.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
def test_model_mesh_components(client):
2+
route = f"/models/vtm_component_indices"
3+
get_full_data = lambda: {"id": "cube"}
4+
json = get_full_data()
5+
response = client.post(route, json=json)
6+
assert response.status_code == 200
7+
uuid_dict = response.json["uuid_to_flat_index"]
8+
assert type(uuid_dict) is dict
9+
10+
indices = list(uuid_dict.values())
11+
indices.sort()
12+
assert indices[0] == 1
13+
assert all(indices[i] == indices[i - 1] + 1 for i in range(1, len(indices)))
14+
15+
16+
def test_extract_brep_uuids(client):
17+
route = "/models/mesh_components"
18+
json_data = {"filename": "cube.og_brep", "geode_object": "BRep"}
19+
20+
response = client.post(route, json=json_data)
21+
22+
assert response.status_code == 200
23+
uuid_dict = response.json["uuid_dict"]
24+
assert isinstance(uuid_dict, dict)
25+
assert (
26+
"Block" in uuid_dict
27+
or "Line" in uuid_dict
28+
or "Surface" in uuid_dict
29+
or "Corner" in uuid_dict
30+
)

0 commit comments

Comments
 (0)