Skip to content

Add Polygons data from Cloud - #14811

Merged
jorgenherje merged 30 commits into
OPM:devfrom
jorgenherje:ri-cloud-api-polygons-per-view-explore
Sep 30, 2026
Merged

jorgenherje merged 30 commits into
OPM:devfrom
jorgenherje:ri-cloud-api-polygons-per-view-explore

Conversation

@jorgenherje

@jorgenherje jorgenherje commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

Add read of metadata and polygons data from Cloud.


Usage of ri-cloud-api to fetch polygons data from Sumo.

The first version provides 3 types of polygons data, based on the defined standard results in Sumo:

  • Field outline
  • Structure depth fault lines (Sumo definition)
  • Fluid Contact outline

We then provide polygons objects in Sumo which are tagged with one of the three standard result tags.

@jorgenherje jorgenherje self-assigned this Sep 28, 2026
@jorgenherje
jorgenherje requested a review from magnesj September 28, 2026 11:21
@jorgenherje jorgenherje added the Enhancement An addition that can be observed by the user label Sep 28, 2026
@magnesj

magnesj commented Sep 29, 2026

Copy link
Copy Markdown
Member

Add icon to RimCloudPolygon
image

@magnesj magnesj left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well organized and easy to read PR.

Two smaller issues to be looked at.

Comment thread ApplicationLibCode/ProjectDataModel/Polygons/Cloud/RimPolygonCloudSource.h Outdated
jorgenherje and others added 25 commits September 30, 2026 13:53
…plied

- caf::PdmUiFormLayoutObjectEditor::createButton now respects the button's isUiReadOnly()/
  uiToolTip() (previously ignored for standalone uiOrdering.addNewButton() buttons, unlike every
  other field editor in this file), so a button can be disabled via setUiReadOnly(true) like any
  other UI item.
- RimPolygonCloudAddress::hasPendingChanges() compares the pending selection fields
  (m_dataSource/m_realization/m_polygonResult/m_name/m_contactType) against the applied ones (and
  is true when nothing has been applied yet). defineUiOrdering() disables the "Apply" button (with
  an explanatory tooltip) whenever there are no pending changes, preventing redundant re-fetches
  and making clear the panel already shows the actual applied selection.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…operty editor

- Create ButtonBox to handle horizontally aligned push buttons
…arison

Replaces the dropdown+Apply/Cancel RimPolygonCloudAddress selection UI with a
browsable, eagerly-built tree of all available polygon results per Sumo data
source (RimPolygonCloudSource root, RimPolygonCloudFolder for structure), with
lazy coordinate fetch only when a leaf is checked visible in a view, eviction
when unchecked everywhere, and comparison against a base realization via a new
visible RimPolygonCloudRealizationGroup sibling.

- New: RimPolygonCloudSource, RimPolygonCloudFolder, RimPolygonCloudRealizationGroup.
- RimPolygonCloudAddress simplified to a fixed-identity leaf (no more pending/
  applied fields, no Apply/Cancel UI); lazy ensureBaseFetched()/evictBaseData()
  and ensureRealizationGroupFetched()/evictRealizationGroup().
- RimPolygonContainer: removed now-unneeded itemsForRealization()/
  displayNameForRealization() virtuals.
- RimPolygonInViewCollection: lazy fetch/eviction wiring, Auto-Follow checkbox
  materializes a comparison realization group checked only in the requesting view.
- RicAddCloudPolygonSourceFeature ("Add Cloud Polygon Source") replaces the
  deleted RicCreateSumoPolygonAddressFeature; RicReloadPolygonCloudAddressFeature
  adapted to refresh base + all existing realization groups.

Build-verified: ApplicationLibCode, Commands, ResInsight-tests all build clean;
ResInsight-tests --gtest_filter=*Polygon* passes 25/25.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1. RimPolygonCloudSource now starts empty (no auto data source/realization
   pre-selection, no immediate buildDirectoryTree()). Data Source and Base
   Realization are editable combo boxes gated behind an Apply button; the
   directory tree is only fetched/built once Apply is clicked. Both fields
   freeze read-only once built.
2. RimPolygonInViewCollection::createSubCollectionInView() now also
   default-unchecks freshly-materialized RimPolygonCloudAddress mirrors (not
   just RimPolygonCloudRealizationGroup), so opening/syncing a view no
   longer eagerly fetches every leaf''s coordinate data.
3. RimPolygonCloudAddress::updateName() no longer repeats the owning
   RimPolygonCloudFolder''s own category label; leaf names now show only the
   distinguishing name/contact type (or a Field Outline fallback).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…InView mirrors

RimNestedMirrorCollectionInView::updateAllViewItems() snapshots sourceItems()
before calling onSynced() (the hook that lazily fetches base data for a
checked RimPolygonCloudAddress) -- so checking a leaf on triggered the fetch
too late to be mirrored into m_itemsInView during that same sync pass, and
nothing appeared in the 3D view until some unrelated later sync happened to
run. Fixed by fetching (if needed) and immediately re-syncing
(updateFromSource()) directly from the m_isChecked fieldChangedByUi handler,
both when checking on (so freshly-fetched RimCloudPolygon children are
mirrored right away) and when unchecking off after an eviction (so
now-stale mirrored items are dropped from the view tree right away).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…), editable Data Source/Base Realization on RimPolygonCloudSource

Request 1: replace the visible RimPolygonCloudRealizationGroup PDM-child mechanism with a
hidden, per-address cache (std::map<int, std::vector<RimPolygon*>>) so a non-base realization
never shows up as an extra node in the main project tree or in another view's mirror. Each
view's RimPolygonInViewCollection mirror now resolves its own effective realization (its
ancestor RimPolygonCloudSource mirror's Auto-Follow state) and substitutes the cached
realization's RimCloudPolygon items directly in place of the address's own base items via
sourceItems()/computeDisplayName()/prepareForSync() -- with no separate visible tree node, so a
view only ever shows exactly one realization per leaf, and the global tree only ever shows the
address's own base/Applied realization.

Request 2: RimPolygonCloudSource's Data Source and Base Realization are now editable after
creation via Apply/Cancel, mirroring the pattern the old RimPolygonCloudAddress had. Apply
either rebuilds the whole folder/leaf tree from scratch (if the data source changed) or evicts
every address's stale base data (if only the base realization changed); Cancel reverts pending
edits with no fetch/rebuild.

Also deletes the now-obsolete RimPolygonCloudRealizationGroup class.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…-select defaults, button box

- RimPolygonCloudSource now emits an objectChanged signal (mirroring
  RimPolygonCloudAddress/RimPolygonFile/RimPolygon) at the end of onApplyClicked(),
  wired via RimPolygonCollection::connectPolygonCloudSourceSignals()/
  onPolygonCloudSourceChanged() (both at creation time and via the recursive
  connectSignalsForContainer() walk for project-load reconnection). Fixes Apply
  building the tree but no open 3D view ever resyncing its RimPolygonInViewCollection
  mirror -- which was also the root cause of a freshly-created address showing an
  empty mirror name (the node never got a chance to sync/name itself).
- Removed RimPolygonInViewCollection's one-shot default-uncheck logic for
  m_useAutoRealization (onSynced() override + m_didApplyDefaultAutoRealization field).
  It was purely cosmetic (a mismatched view already falls back to the base
  realization regardless of the checkbox state, and is shown disabled+tooltipped) and
  timing-sensitive -- removing it lets the checkbox keep its true constructor default
  permanently, as intended.
- RicAddCloudPolygonSourceFeature now pre-selects the first available Data Source and
  Realization on a newly created RimPolygonCloudSource (via the existing
  setDataSource()/setBaseRealization() one-shot setup setters), without auto-applying:
  Apply remains required since hasPendingChanges() stays true until the directory is
  actually built.
- RimPolygonCloudSource::defineUiOrdering() now uses caf::PdmUiButtonBox for
  Apply/Cancel (a real QDialogButtonBox) instead of two separate addNewButton() calls,
  matching the framework helper already added earlier for this exact adjacent,
  right-aligned button layout.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tion

RimPolygonInViewCollection::computeDisplayName() previously only special-cased a
RimPolygonCloudAddress source -- the source's own top mirror node (whose
sourceCollection() is the RimPolygonCloudSource itself) always fell back to
src->collectionName(), which is fixed to the source's own Applied base realization
(e.g. 'iter-0 (case) / Real 0') regardless of what realization the view was actually
Auto-Following (e.g. Real 1). Child address leaves already showed the effective
realization correctly via their own '(Real N)' suffix, making the mismatch visible.

Refactored RimPolygonCloudSource::updateName() into a shared composeName(int
realization) helper and exposed it as nameForRealization(int), then extended
computeDisplayName() with a RimPolygonCloudSource branch that substitutes the
effective realization into the composed name (replacing the base realization,
avoiding a redundant second 'Real' suffix) whenever it differs from the source's own
Applied base realization.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… project tree on fetch

1. RimPolygonInViewCollection::defineUiOrdering() only ever adds m_useAutoRealization
   when sourceCollection()->supportsRealizationOverride() is true (only
   RimPolygonCloudSource mirror nodes) -- but it never called
   uiOrdering.skipRemainingFields(), so caf's generic 'auto-append any field not
   explicitly ordered' behavior still surfaced the (non-hidden) checkbox on every
   other mirror node (folders, name-folders, address leaves). Fixed by calling
   skipRemainingFields() unconditionally at the end of defineUiOrdering().

2. RimPolygonCloudAddress::ensureBaseFetched()/evictBaseData() only emitted
   objectChanged (refreshing open 3D views' polygon mirrors) but never called
   uiCapability()->updateAllRequiredEditors() -- so newly-fetched (or newly-evicted)
   RimCloudPolygon children never showed up under the address's own node in the main
   project tree, even though they were correctly added as PDM children. This meant
   unchecking Auto-Follow (so a view shows the source's own base realization) did
   fetch the data, but it stayed invisible in RimPolygonCloudSource's own tree
   structure. Fixed by adding the missing updateAllRequiredEditors() call to both,
   matching the established convention used elsewhere for structural tree refreshes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Yes -- the cache was being cleared. RimPolygonCloudSource::evictUnusedRealizationData()
(called whenever the Auto-Follow checkbox changed) evicted an address's base data
whenever the current view, after the toggle, no longer effectively resolved to the
base realization -- e.g. re-enabling Auto-Follow on a view whose case matches and is
on a non-base realization made the base realization 'not in use anywhere', deleting
the address's own (persistent, always-in-the-project-tree) base RimCloudPolygon
children even though the leaf's own checkbox was still checked the whole time.

Base data is the address's canonical, project-tree-visible identity and must only be
evicted when the leaf's own checkbox is actually unchecked in every view (already
handled separately in RimPolygonInViewCollection::fieldChangedByUi's m_isChecked
branch) -- not merely because Auto-Follow currently causes some other realization to
be displayed instead. Fixed by removing the base-eviction check from
evictUnusedRealizationData(), which now only evicts unused cached comparison
realizations (as intended), leaving base data untouched.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…even if Auto-Follow shows a different one

UX request: enabling a leaf's checkbox in a view should always populate the address's
base realization data (in the project tree), regardless of whether Auto-Follow is
currently making that view display a different (comparison) realization instead. This
makes the base realization's polygons consistently available -- e.g. for another view,
or simply for inspection in the project tree -- without requiring the user to also
visit a view whose case actually matches the base realization.

- RimPolygonInViewCollection::prepareForSync() now unconditionally calls
  address->ensureBaseFetched(), then additionally calls
  address->ensureRealizationFetched(realization) when the view's effective realization
  differs from the base -- instead of fetching only one or the other.
- Base eviction was previously gated on isRealizationInUseInAnyView(address,
  baseRealization) (i.e. only kept if some view's *effective* realization was the base
  one), which no longer matches the fetch behavior above. Added
  isCheckedInAnyView(address) (checked in any view, regardless of which realization
  that view currently shows) and use it instead: base data is now evicted only when
  the leaf is unchecked in every view, matching its new 'always fetched while checked
  anywhere' semantics.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause of yet another instance of the eviction confusion: unchecking a
RimPolygonCloudAddress leaf's own visibility checkbox in its last remaining view still
evicted the address's base RimCloudPolygon data whenever no view was left with the
leaf checked -- deleting it from the main project tree, not just hiding it from the
3D view. This contradicts how every other polygon container's visibility checkbox
behaves (hide, never delete) and directly conflicts with the just-added 'always fetch
base while any view has this leaf checked' behavior, since simply toggling visibility
off in the only view checking it would immediately undo that guarantee.

Fixed by removing base-data eviction from the m_isChecked-unchecked handler entirely.
Base data is now only ever discarded by an explicit user action (the 'Reload' command,
via RicReloadPolygonCloudAddressFeature::evictBaseData()) or when the project itself is
closed/reloaded -- exactly matching the already-established 'coordinate data is not
persisted, refetched on project (re)load' contract, and how RimPolygonFile-imported
polygons already behave (a visibility checkbox never destroys the underlying data).
Comparison (non-base) realization caches are still evicted on uncheck as before, since
those are explicitly transient per-view aids, not the address's canonical identity.
Removed the now-unused isCheckedInAnyView() helper added in the previous, superseded
attempt at this fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…y hide

Extends the base-data hide-only policy to comparison-realization caches
as well. Unchecking a leaf's visibility, or toggling Auto-Follow View
Realization, no longer evicts any RimCloudPolygon data.

Root cause of the reported bug: the mirror-tree sync
(RimNestedMirrorCollectionInView::updateAllViewItems) matches mirror
children to source children by pointer identity on every sync pass. If
an eviction call deletes the underlying RimCloudPolygon objects a
mirror pointed at, the very next sync silently drops the now-dangling
mirror wrapper -- which is how unchecking a checkbox ended up emptying
the RimPolygonCloudSource tree structure, even though visibility
filtering (visiblePolygonsInView()) never required removing any mirror
children or cached data to correctly hide/show polygons in the 3D view.

Eviction is now exclusively a manual action via the Reload command
(RicReloadPolygonCloudAddressFeature), which evicts+refetches
independently of any is this still in use anywhere check. This matches
the accepted v1 trade-off that Sumo polygon data is not persisted and
is refetched on project reload; unbounded memory growth within a
single session is accepted.

Removed now-fully-dead code: RimPolygonCloudAddress::evictAllUnusedRealizations(),
RimPolygonCloudSource::evictUnusedRealizationData(),
RimPolygonInViewCollection::isRealizationInUseInAnyView()/isCheckedInAnyView(),
and RimPolygonInViewCollection::findMirrorForSource() -- all had zero
remaining callers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Changed the disambiguation suffix used when a fetched Sumo polygon
result has multiple distinct POLY_ID groups sharing the same name
from 'Name (n)' to 'Name (ID: n)', to make it clear the parenthesized
number is the underlying polygon id, not e.g. a count or index.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t checked-but-inert

The checkbox was correctly disabled (read-only) with an explanatory
tooltip when the view's case belongs to a different Sumo case/ensemble
than the source's data source, but still displayed as checked -- since
it directly showed the real, persisted m_useAutoRealization field,
which defaults to true and is otherwise untouched in this state.
Checked-but-disabled looks like 'this is on and doing something',
which is misleading: in this state Auto-Follow has zero effect
(effectiveRealization() already falls back the same whether checked or
unchecked here).

Added a non-persisted UI-only shadow field, m_useAutoRealizationUiState,
shown in the checkbox in place of the real field. When the view's case
doesn't match, the shadow is forced to false (and read-only) for
display purposes only -- the real, persisted m_useAutoRealization is
left untouched, so it takes effect again automatically the moment the
view's case starts matching, without needing any of the one-shot
mutating-uncheck machinery removed earlier in this series (which had
its own timing bugs). When the case matches, the shadow simply mirrors
the real field and any user edit is written straight back to it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…lygon cloud source'

The tooltip shown when the Auto-Follow View Realization checkbox is
disabled referred to 'this polygon address'/'the address's own
Applied realization', which was stale wording from before the tree
redesign -- the checkbox now lives on the RimPolygonCloudSource mirror
node, not a RimPolygonCloudAddress leaf. Updated to 'this polygon
cloud source' / 'the polygon source's own Applied realization'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…d marker

- Add Download.svg icon (24x24 stroke style matching Refresh.svg), registered in ResInsight.qrc.
- RimPolygonCloudAddress::defineObjectEditorAttribute() now shows, only while !hasBaseData():
  - a clickable download-icon tag wired to a new onDownloadTagClicked() handler that calls
    ensureBaseFetched() directly from the project tree (independent of any view's visibility
    checkbox, which still auto-fetches exactly as before), then refreshes the tree/views via
    updateAllRequiredEditors() + objectChanged.send().
  - a plain, unobtrusive '[Not fetched]' text tag (white background, dark gray text) replacing
    the earlier blue pill-style tag.
- Once hasBaseData() is true, no tags are drawn at all.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jorgenherje
jorgenherje force-pushed the ri-cloud-api-polygons-per-view-explore branch from 1bbaf89 to 0b0643d Compare September 30, 2026 12:43
@jorgenherje
jorgenherje requested a review from magnesj September 30, 2026 12:43
@jorgenherje
jorgenherje merged commit 52f9cdf into OPM:dev Sep 30, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement An addition that can be observed by the user

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants