|
15 | 15 | ) |
16 | 16 | from flow360.component.simulation.framework.base_model import Flow360BaseModel |
17 | 17 | from flow360.component.simulation.framework.entity_base import EntityList |
| 18 | +from flow360.component.simulation.framework.entity_registry import EntityRegistry |
18 | 19 | from flow360.component.simulation.framework.param_utils import AssetCache |
19 | 20 | from flow360.component.simulation.outputs.outputs import ( |
20 | 21 | SurfaceIntegralOutput, |
@@ -498,6 +499,31 @@ def _set_up_default_reference_geometry(params: SimulationParams, length_unit: Le |
498 | 499 | return params |
499 | 500 |
|
500 | 501 |
|
| 502 | +def _build_deduplicated_entity_registry_from_params(params: SimulationParams) -> EntityRegistry: |
| 503 | + """ |
| 504 | + Build a deduplicated entity registry from params' stored entities. |
| 505 | +
|
| 506 | + params.used_entity_registry may contain duplicates (same entity used in multiple |
| 507 | + models/outputs). This function deduplicates by (entity_type, identifier), where |
| 508 | + identifier is private_attribute_id when available, falling back to entity name |
| 509 | + to avoid collapsing distinct entities that share a None id. |
| 510 | + """ |
| 511 | + registry = EntityRegistry() |
| 512 | + seen_keys = set() |
| 513 | + for entity_type, entities in params.used_entity_registry.internal_registry.items(): |
| 514 | + for entity in entities: |
| 515 | + identifier = ( |
| 516 | + entity.private_attribute_id |
| 517 | + if entity.private_attribute_id is not None |
| 518 | + else entity.name |
| 519 | + ) |
| 520 | + key = (entity_type, identifier) |
| 521 | + if key not in seen_keys: |
| 522 | + registry.register(entity) |
| 523 | + seen_keys.add(key) |
| 524 | + return registry |
| 525 | + |
| 526 | + |
501 | 527 | def set_up_params_for_uploading( # pylint: disable=too-many-arguments |
502 | 528 | root_asset, |
503 | 529 | length_unit: LengthType, |
@@ -557,12 +583,13 @@ def set_up_params_for_uploading( # pylint: disable=too-many-arguments |
557 | 583 | # Legacy workflow (without DraftContext): use root_asset.entity_info |
558 | 584 | # User may have made modifications to the entities which is recorded in asset's entity registry |
559 | 585 | # We need to reflect these changes. |
560 | | - root_asset.entity_info.update_persistent_entities( |
561 | | - asset_entity_registry=root_asset.internal_registry |
| 586 | + entity_info = root_asset.entity_info |
| 587 | + entity_info.update_persistent_entities( |
| 588 | + asset_entity_registry=_build_deduplicated_entity_registry_from_params(params) |
562 | 589 | ) |
563 | 590 |
|
564 | 591 | # Check if there are any new draft entities that have been added in the params by the user |
565 | | - entity_info = _set_up_params_non_persistent_entity_info(root_asset.entity_info, params) |
| 592 | + entity_info = _set_up_params_non_persistent_entity_info(entity_info, params) |
566 | 593 |
|
567 | 594 | # If the customer just load the param without re-specify the same set of entity grouping tags, |
568 | 595 | # we need to update the entity grouping tags to the ones in the SimulationParams. |
|
0 commit comments