Skip to content

Commit fae6cbf

Browse files
feat(): Added bodies_face_edge_ids and also property functions to replace existing face/edge/body_ids (#1671)
1 parent b0ecbe5 commit fae6cbf

File tree

17 files changed

+2671
-47
lines changed

17 files changed

+2671
-47
lines changed

.pre-commit-config.yaml

Lines changed: 0 additions & 29 deletions
This file was deleted.

flow360/component/project_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,10 @@ def _get_used_tags(model: Flow360BaseModel, target_entity_type, used_tags: set):
479479
(Surface, "face_group_tag"),
480480
]
481481

482-
if entity_info.edge_ids:
482+
if entity_info.all_edge_ids:
483483
entity_types.append((Edge, "edge_group_tag"))
484484

485-
if entity_info.body_ids:
485+
if entity_info.all_body_ids:
486486
entity_types.append((GeometryBodyGroup, "body_group_tag"))
487487

488488
for entity_type, entity_grouping_tags in entity_types:

flow360/component/simulation/entity_info.py

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from abc import ABCMeta, abstractmethod
44
from collections import defaultdict
5-
from typing import Annotated, List, Literal, Optional, Union
5+
from typing import Annotated, Dict, List, Literal, Optional, Union
66

77
import pydantic as pd
88

@@ -84,11 +84,31 @@ def get_persistent_entity_registry(self, internal_registry, **kwargs):
8484
"""
8585

8686

87+
class BodyComponentInfo(Flow360BaseModel):
88+
"""Data model for body component info."""
89+
90+
face_ids: list[str] = pd.Field(
91+
description="A full list of face IDs that appear in the body.",
92+
)
93+
edge_ids: Optional[list[str]] = pd.Field(
94+
None,
95+
description="A full list of edge IDs that appear in the body. Optional for surface mesh geometry.",
96+
)
97+
98+
8799
class GeometryEntityInfo(EntityInfoModel):
88100
"""Data model for geometry entityInfo.json"""
89101

90102
type_name: Literal["GeometryEntityInfo"] = pd.Field("GeometryEntityInfo", frozen=True)
91103

104+
bodies_face_edge_ids: Optional[Dict[str, BodyComponentInfo]] = pd.Field(
105+
None,
106+
description="Mapping from body ID to the face and edge IDs of the body.",
107+
)
108+
# bodies_face_edge_ids: Mostly just used by front end. On python side this
109+
# is less useful as users do not operate on face/body/edge IDs directly.
110+
# But at least this can replace `face_ids`, `body_ids`, and `edge_ids` since these contains less info.
111+
92112
body_ids: list[str] = pd.Field(
93113
[],
94114
description="A full list of body IDs that appear in the geometry.",
@@ -155,6 +175,45 @@ class GeometryEntityInfo(EntityInfoModel):
155175
description="The default value based on uploaded geometry for geometry_accuracy.",
156176
)
157177

178+
@property
179+
def all_face_ids(self) -> list[str]:
180+
"""
181+
Returns a full list of face IDs that appear in the geometry.
182+
Use `bodies_face_edge_ids` if available, otherwise fall back to use `face_ids`.
183+
"""
184+
if self.bodies_face_edge_ids is not None:
185+
return [
186+
face_id
187+
for body_component_info in self.bodies_face_edge_ids.values()
188+
for face_id in body_component_info.face_ids
189+
]
190+
return self.face_ids
191+
192+
@property
193+
def all_edge_ids(self) -> list[str]:
194+
"""
195+
Returns a full list of edge IDs that appear in the geometry.
196+
Use `bodies_face_edge_ids` if available, otherwise fall back to use `edge_ids`.
197+
"""
198+
if self.bodies_face_edge_ids is not None:
199+
return [
200+
edge_id
201+
for body_component_info in self.bodies_face_edge_ids.values()
202+
# edge_ids can be None for surface-only geometry; treat it as an empty list.
203+
for edge_id in (body_component_info.edge_ids or [])
204+
]
205+
return self.edge_ids
206+
207+
@property
208+
def all_body_ids(self) -> list[str]:
209+
"""
210+
Returns a full list of body IDs that appear in the geometry.
211+
Use `bodies_face_edge_ids` if available, otherwise fall back to use `body_ids`.
212+
"""
213+
if self.bodies_face_edge_ids is not None:
214+
return list(self.bodies_face_edge_ids.keys())
215+
return self.body_ids
216+
158217
def group_in_registry(
159218
self,
160219
entity_type_name: Literal["face", "edge", "body", "snappy_body"],
@@ -420,7 +479,7 @@ def get_persistent_entity_registry(self, internal_registry, **_) -> EntityRegist
420479
"face", face_group_tag, registry=internal_registry
421480
)
422481

423-
if len(self.edge_ids) > 0:
482+
if len(self.all_edge_ids) > 0:
424483
if self.edge_group_tag is None:
425484
edge_group_tag = self._get_default_grouping_tag("edge")
426485
log.info(f"Using `{edge_group_tag}` as default grouping for edges.")
@@ -467,7 +526,7 @@ def create_group_to_sub_component_mapping(group):
467526
# This likely means the geometry asset is pre-25.5.
468527
raise ValueError(
469528
"Geometry cloud resource is too old."
470-
" Please consider re-uploading the geometry with newer solver version."
529+
" Please consider re-uploading the geometry with newer solver version (>25.5)."
471530
)
472531

473532
face_group_by_body_id_to_face = create_group_to_sub_component_mapping(

flow360/component/simulation/translator/surface_meshing_translator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ def snappy_mesher_json(input_params: SimulationParams):
292292

293293
# extract geometry information in body: {patch0, ...} format
294294
bodies = {}
295-
for face_id in input_params.private_attribute_asset_cache.project_entity_info.face_ids:
295+
for face_id in input_params.private_attribute_asset_cache.project_entity_info.all_face_ids:
296296
solid = face_id.split("::")
297297
if solid[0] not in bodies:
298298
bodies[solid[0]] = set()
@@ -549,7 +549,7 @@ def legacy_mesher_json(input_params: SimulationParams):
549549
input_params.private_attribute_asset_cache.project_entity_info, GeometryEntityInfo
550550
)
551551

552-
for face_id in input_params.private_attribute_asset_cache.project_entity_info.face_ids:
552+
for face_id in input_params.private_attribute_asset_cache.project_entity_info.all_face_ids:
553553
if face_id not in face_config:
554554
face_config[face_id] = {"maxEdgeLength": default_max_edge_length}
555555

flow360/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
version
33
"""
44

5-
__version__ = "25.8.1b1"
5+
__version__ = "25.8.2b1"
66
__solver_version__ = "release-25.8"

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "flow360"
3-
version = "v25.8.1b1"
3+
version = "v25.8.2b1"
44
description = "Flow360 Python Client"
55
authors = ["Flexcompute <[email protected]>"]
66

tests/ref/simulation/service_init_geometry.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "25.8.1b1",
2+
"version": "25.8.2b1",
33
"unit_system": {
44
"name": "SI"
55
},

tests/ref/simulation/service_init_surface_mesh.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "25.8.1b1",
2+
"version": "25.8.2b1",
33
"unit_system": {
44
"name": "SI"
55
},

tests/ref/simulation/service_init_volume_mesh.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "25.8.1b1",
2+
"version": "25.8.2b1",
33
"unit_system": {
44
"name": "SI"
55
},

tests/simulation/converter/ref/ref_monitor.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "25.8.1b1",
2+
"version": "25.8.2b1",
33
"unit_system": {
44
"name": "SI"
55
},

0 commit comments

Comments
 (0)