Skip to content

#947 PDM: Add caf::PdmNestedCollection template and migrate surface + polygon collections#949

Open
magnesj wants to merge 6 commits into
devfrom
feature/947-pdm-hierarchical-collection
Open

#947 PDM: Add caf::PdmNestedCollection template and migrate surface + polygon collections#949
magnesj wants to merge 6 commits into
devfrom
feature/947-pdm-hierarchical-collection

Conversation

@magnesj
Copy link
Copy Markdown
Owner

@magnesj magnesj commented May 8, 2026

Summary

Introduces a CRTP template caf::PdmNestedCollection<SelfT, ItemT> that extends caf::PdmObjectCollection<ItemT> with a user-visible collection name and a vector of subcollections of the derived type. This generalizes the "name + items + subcollections-of-self" pattern previously hand-rolled in RimSurfaceCollection and RimPolygonCollection.

A non-templated caf::PdmNestedCollectionInterface lets generic command features operate on any nested collection without knowing the template parameters. Includes a canAddSubCollection() query so leaf containers (e.g. file-backed folders) can refuse new sub-collections and let the generic UI hide the corresponding action.

A parallel CRTP template RimNestedMirrorCollectionInView<SelfT, SourceT, ItemViewT> collapses the hand-rolled in-view mirror sync logic in RimPolygonInViewCollection into a few small overrides. The same template can drop into RimSurfaceInViewCollection next.

XML keywords are kept in the derived constructors so existing project files load unchanged. Legacy RimPolygonCollection::m_polygonFiles is migrated into the new m_subCollections in initAfterRead.

Changes

caf framework

  • New Fwk/AppFwk/cafProjectDataModel/cafPdmNestedCollection.{h,inl} — CRTP template providing collectionName/setCollectionName, subCollections, addSubCollection, addNewSubCollection, findSubCollectionByName, allItems, setAsTopmostFolder, plus userDescriptionField and defineUiOrdering overrides.
  • New Fwk/AppFwk/cafProjectDataModel/cafPdmNestedCollectionInterface.h — non-templated interface for generic features (canAddSubCollection, addNewSubCollection, collectionName/setCollectionName).
  • Modified cafPdmObjectCollection.h/.inl — replace is_base_of static_assert with a C++20 DerivedFromPdmObject concept, evaluated lazily inside the constructor so derived types may be forward-declared at the point the class template is instantiated as a base.

Generic command

  • New RicNewNestedCollectionFeature.{h,cpp} — generic "Add Folder" command that operates on any PdmNestedCollectionInterface and is disabled on leaves via canAddSubCollection().
  • Removed RicNewSurfaceCollectionFeature.{h,cpp} — superseded.

Surfaces

  • Modified RimSurfaceCollection.{h,cpp} — inherit from PdmNestedCollection, drop ~80 lines of duplicated boilerplate; preserves setAsTopmostFolder semantics.
  • Modified RimEnsembleSurface.cppgetSubCollectionfindSubCollectionByName.

Polygons

  • New RimPolygonContainer.{h,cpp} — XML-abstract base for both RimPolygonCollection (folder) and RimPolygonFile (file-backed leaf folder). Both live polymorphically in the inherited m_subCollections, so the in-view mirror picks them up uniformly.
  • Modified RimPolygonCollection.{h,cpp} — inherit from RimPolygonContainer; legacy m_polygonFiles field migrated into m_subCollections in initAfterRead and disabled for write. userDefinedPolygons() removed in favor of allPolygons().
  • Modified RimPolygonFile.{h,cpp} — inherit from RimPolygonContainer; overrides canAddSubCollection() → false. Reuses "Name" keyword for m_collectionName for backward compatibility.

In-view mirror

  • New RimNestedMirrorCollectionInView.{h,inl} — CRTP template for view-side mirrors of nested source collections. Derived classes adapt to their source type via three small hooks.
  • Modified RimPolygonInViewCollection.{h,cpp} — migrated to the new template; ~150 lines of hand-rolled sync removed.

Docs

  • New docs/pdm-nested-collection-design.md — records the line-count comparison and the trade-off behind keeping the templated design over a non-templated alternative.

Closes #947.

@magnesj magnesj force-pushed the feature/947-pdm-hierarchical-collection branch from 07c3849 to f834267 Compare May 8, 2026 10:59
@magnesj magnesj changed the title #947 PDM: Add caf::PdmHierarchicalCollection template #947 PDM: Add caf::PdmNestedCollection template and migrate surface + polygon collections May 10, 2026
@magnesj magnesj force-pushed the feature/947-pdm-hierarchical-collection branch 3 times, most recently from 9fe3c1d to 6e1c9d8 Compare May 12, 2026 11:05
magnesj added 4 commits May 12, 2026 14:23
Introduce a shared base for tree-shaped folder containers that hold a
list of leaf items together with a list of subcontainers of the same
kind. Replaces the per-class plumbing (subcollections field, top-folder
flag, add/remove/find sub-collection, factory) that is duplicated across
RimSurfaceCollection, RimPolygonCollection and similar candidates.

- caf::PdmNestedCollectionBase: non-templated PdmObject base exposing
  collection-name, add-new-subcollection, leaf-check and topmost-folder
  marking for generic command features and script methods.
- caf::PdmNestedCollection<SelfT, ItemT>: CRTP template that owns the
  typed m_subCollections field and inherits the m_items array from
  PdmObjectCollection<ItemT>. Provides allItems(), find-sub-collection,
  and a typed factory hook.
- RimNestedMirrorCollectionInView: view-side analogue for in-view
  collections that mirror a nested source collection, with orphan-sweep
  + find-or-create + reorder sync.

Design rationale (templated vs non-templated, break-even on derived
class count) lives in docs/pdm-nested-collection-design.md.

No callers migrated in this commit.
…n test

IconProvider::operator= copied a new resource-string but never cleared
the existing m_pixmap. icon() prefers the pixmap when present, so a
pixmap-based default stamped earlier (e.g. by a base class) would
silently shadow a later resource-string-only assignment in a derived
class.

Reset m_pixmap in operator= so resource-string-only assignments fully
replace pixmap-based ones, and cover the replacement semantics with a
caf::IconProvider regression test: default-overwriting-pixmap,
resource-string-overwriting-pixmap and pixmap-overwriting-pixmap.

Needed for the upcoming nested-collection migration where a base class
stamps a folder pixmap and the topmost instance applies a branded
resource-string icon on top.
…tionBase

Generalise the per-domain "Add Folder" command and the scripting-side
add-folder method so they work against any container that exposes
caf::PdmNestedCollectionBase.

- RicNewNestedCollectionFeature: command feature that walks the
  selected PdmObject up to the nearest PdmNestedCollectionBase ancestor
  and calls addNewSubCollection(). Hidden via canAddSubCollection() for
  leaf containers.
- RimcNestedCollectionBase: scripting wrapper exposing the same
  add-sub-collection action through the Python interface, so generated
  Python bindings get the operation for free on every derived class.

Neither is wired to a concrete collection yet; the per-domain features
remain in place until the migration commit replaces them.
…llection

Port RimSurfaceCollection, RimPolygonCollection and the polygon-in-view
side onto the new caf::PdmNestedCollection framework, replacing the
per-class folder plumbing (m_subCollections field, topmost-folder flag,
add/remove/find sub-collection, factory, "new folder" command) with the
shared base.

- RimSurfaceCollection and RimPolygonCollection now derive from
  caf::PdmNestedCollection. Each constructor uses the generic folder
  icon and exposes a static createTopmost() that marks the top instance
  and applies the branded domain icon; RimOilField calls the factory.
- RimPolygonInViewCollection uses the new RimNestedMirrorCollectionInView
  helper, and a new RimPolygonContainer carries the source-side polygon
  link.
- RicNewSurfaceCollectionFeature is removed; the generic
  RicNewNestedCollectionFeature drives the "Add Folder" action against
  both collections.
- Update callers (RimAnnotationCollection, RimEnsembleSurface, polygon
  command features) and the scripting wrapper (RimcSurfaceCollection),
  plus the Python add-folder binding and polygon test.
@magnesj magnesj force-pushed the feature/947-pdm-hierarchical-collection branch from 6e1c9d8 to 1e45c68 Compare May 12, 2026 12:28
magnesj added 2 commits May 13, 2026 14:12
Replace the dynamic_cast dispatch in RimPolygonCollection::loadData() with a
virtual loadData() on RimPolygonContainer. The base recurses through
subCollections; RimPolygonFile overrides to load file data. The folder
RimPolygonCollection no longer needs its own loadData().

Move RimPolygonFile::canAddSubCollection() and RimPolygonInView::sourceItem()
implementations from headers to .cpp.

Simplify std::unexpected calls in RimcNestedCollectionBase by removing
redundant explicit QString construction.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generalize hierarchical PDM collections (RimSurfaceCollection-style)

1 participant