Commit Graph
1605 Commits
Author SHA1 Message Date
Kristian Bendiksen 79442c0524 #14274 Fix invalid index range in dataChanged() from table row editor
Valid Qt column indices are 0..columnCount()-1, but the bottom-right
model index was constructed with column columnCount(). Since
QAbstractItemModel::index() validates its arguments, this produced an
invalid QModelIndex(-1,-1) passed to dataChanged(), causing a console
warning on every table row update, e.g. when adding or moving 3D well
path pick targets. Fix the same off-by-one in modelIndexFromPdmObject().

Fixes #14274.
2026-07-27 10:10:25 +02:00
Kristian Bendiksen cf5a0c5227 #10988 Fix QItemSelectionModel warning when exiting application
The tree view in PdmUiTreeSelectionEditor is deleted using deleteLater(),
while the models are children of the editor and are deleted immediately.
Detach the view from the models in the destructor, otherwise pending events
in the view may operate on a selection model whose model has been destroyed.
2026-07-27 09:01:10 +02:00
Magne Sjaastad c0059da42c #14306 Fix orphaned progress dialog when importing summary ensembles
Driving caf::ProgressInfo from worker threads inside the OpenMP loop in
loadFileSummaryCaseData() marshaled setProgress() to the GUI thread via a
queued connection. These updates could be delivered after the ProgressInfo
scope had ended and the progress stacks were popped, accessing an empty stack
and resurrecting the just-closed dialog stuck at 0% with no way to close it.

Only update the progress dialog from the master thread, using an atomic
counter for a monotonic progress value, and guard the ProgressInfo mutators
against stale updates delivered after the stacks are empty.
2026-06-25 09:56:22 +02:00
Magne Sjaastad f45d56730c #14306 Guard progress dialog event processing against re-entrant recursion 2026-06-24 15:34:40 +02:00
Magne Sjaastad d5c87317c3 #14306 Add test reproducing recursive event processing in progress dialog 2026-06-24 15:34:40 +02:00
Magne Sjaastad 74c9be7aaa #14285 Fix crash when text label projects to an undefined position 2026-06-23 07:35:45 +02:00
Magne Sjaastad 1858529f7d #14266 Fix crash when activating combo box with stale option index 2026-06-23 07:31:55 +02:00
Magne Sjaastad d7d3938986 #14279 Guard line editor editing-finished against deleted field 2026-06-23 07:31:21 +02:00
Kristian Bendiksen 8209bd3ecf #14230 Fix deadlock when importing wells from OSDU
The GUI thread deadlocked on a non-recursive QMutex during OSDU well
import. The download-completion slots and DataLoadController::onTaskFinished
held a mutex while triggering progress updates, which call
QApplication::processEvents(). That re-enters the event loop and dispatches
another queued parquet-download-complete event for a different well, whose
handler then blocks trying to lock the same mutex.

Release the mutex before emitting taskDone in the OSDU well path and well
log data loaders, and before calling incrementProgress() in onTaskFinished.
The map access that the mutex protects stays inside the locked scope; the
captured ProgressInfo outlives the call (kept alive by blockUntilDone) and
incrementProgress() is thread-safe via self-marshaling to the GUI thread.

Fixes #14230.
2026-06-18 07:55:04 +02:00
jonjenssen a82b8f5753 Fix reading old projects and restore plot views
Fix crash at exit in plot window
2026-06-17 13:55:32 +02:00
Kristian Bendiksen ef815a79f8 #14167 Fix table dropdown needing two clicks when moving to another row
The table model shares one field editor handle per column across all rows.
When an edit ends, the view schedules the editor widget for deletion with
deleteLater(), but the handle's QPointer stays valid until the deferred
deletion runs. Clicking a cell in the same column of another row reused that
doomed widget as the new cell editor, so it was destroyed right after
opening and the user had to click again. Moving horizontally was unaffected
since a different column uses a different editor handle.

Cancel the pending deferred deletion before handing the widget out again,
and guard against a null editor widget.
2026-06-10 18:01:00 +02:00
Kristian Bendiksen 417e515d3d #14167 Sector Model: Open BCPROP dropdowns on first click
The boundary conditions table required several clicks in each cell before
a value could be changed, because the table view used Qt's default edit
triggers. Add an opt-in editOnSingleClick attribute to the table view
editor that starts editing on a single click and opens combo box popups
immediately, and enable it for the BCPROP keywords table.
2026-06-10 18:01:00 +02:00
Magne Sjaastad f7ccfcfff6 #14182 Fix stack overflow when destroying deep AABB bounding box trees
The bounding box tree is destroyed by deleteInternalNodesBottomUp, which
recursed once per tree level. For deep or unbalanced trees this overflowed
the call stack during project close (RigMainGrid destruction).

Replace the recursion with an explicit stack. Deleting an internal node does
not touch its children, so the child pointers are read before the node is
deleted and the deletion order is irrelevant. Leaf nodes remain pooled and
are not deleted individually.
2026-06-10 08:57:39 +02:00
Magne Sjaastad eb3b5f14b5 #14178 Fix crash in slider editor from re-entrant field write
The integer slider editor cross-updated the spin box and slider without blocking signals, so a single user interaction wrote to the PDM field twice. The first (nested) write could trigger a field-changed callback that rebuilt the property panel and destroyed the spin box internal line edit, after which the second write dereferenced the dangling line edit in QAbstractSpinBox::text() and crashed.

Block the other widget signals while programmatically syncing in slotSliderValueChanged and updateSliderPosition, restoring the previous blocked state so it nests safely with configureAndUpdateUi. Add null guards in updateSliderPosition and writeValueToField.
2026-06-10 08:46:14 +02:00
Magne Sjaastad 5dae9a0a19 #14104 Fix property dialogs opening collapsed on multi-monitor setups
The export property dialogs that rely solely on sizeHint() could open collapsed when shown on a screen whose DPI differs from the screen they were built on. Recompute the layout on first show, after the dialog is associated with its destination screen, by calling adjustSize() in showEvent when no stored size is restored. Also give RiuPropertyViewTabWidget a minimum size floor so the inner scroll area's artificially small minimum width cannot collapse the dialog.
2026-06-08 16:32:36 +02:00
Magne Sjaastad 1989f93440 #14104 Store dialog size as plain width/height instead of binary geometry
Replace the binary QWidget::saveGeometry()/restoreGeometry() encoding used by PdmUiPropertyViewDialog and RiuPropertyViewTabWidget with plain integer width and height values in QSettings, restored with resize(). The stored values are human-readable and not tied to Qt internal geometry-stream version. Only the size is persisted; the window position is left to the window manager to avoid restoring dialogs off-screen or on a disconnected monitor.
2026-06-08 16:32:36 +02:00
Magne Sjaastad 96eaa2cff3 #14146 Guard against degenerate viewport in scale legend tick generation. A tiny viewport yields a zero tick count, and a zero domain range along the active axis combined with the division produced a non-finite step size that triggered an assert/abort in TickMarkGenerator. Skip the legend update for these degenerate cases. 2026-06-08 15:54:05 +02:00
Magne Sjaastad 98ea83146a #14122 Allow tree selection editor to grow only when it is the last row
The tree selection editor can grow to a large height, which is useful when it is the last field editor in the property dialog. When other field editors are located below, the heightHint is now used as the maximum height instead. The form layout tracks whether an editor occupies the bottom-most row of the form and passes this to the editor. In the Analysis Plot, the time step selection is constrained to its height hint because other input fields are located below it.
2026-06-05 16:28:22 +02:00
Magne Sjaastad 8606fa002e #14104 Remember user-defined size of property and preferences dialogs
Persist the geometry of PdmUiPropertyViewDialog and RiuPropertyViewTabWidget to the application settings on close and restore it on the next show. Restoring is done in showEvent rather than the constructor so it is applied reliably for a modal dialog. The settings key includes the bound object class keyword so distinct dialogs that share a window title do not collide.

This behaviour is gated behind a new "Remember Dialog Size" experimental feature, disabled by default. PdmUiPropertyViewDialog cannot access RiaPreferencesSystem, so the application pushes the current setting via the static enableGeometryPersistence(), following the existing pattern used for class-name display. RiuPropertyViewTabWidget queries the feature directly.
2026-06-04 21:06:38 +02:00
Magne Sjaastad 9c857288da #14104 Add minimum size floor to property view dialog
Override sizeHint() and minimumSizeHint() in PdmUiPropertyViewDialog so the dialog cannot open collapsed. The inner scroll area reports an artificially small minimum size hint that some window managers honor literally, shrinking the dialog to an unusable size (issue #14104). The floor is capped by the content's preferred size so intentionally small dialogs are not enlarged.
2026-06-04 21:06:38 +02:00
Magne Sjaastad 99fdcc9a9a AppFwk: make PdmUiTreeOrdering::add null-tolerant and clean up containsField
The add() overloads aborted via CAF_ASSERT when passed a null field or
object, forcing every call site that adds an optional child to pre-guard.
Adding an optional node is inherently an "add it if it exists" operation,
so make both overloads a no-op on null instead: the field overload returns,
and the object overload returns nullptr. This removes a class of latent
release crashes and the need for repetitive null checks at call sites.

Also remove a redundant dynamic_cast (and its "// What ???" comment) in
containsField, since child() already returns PdmUiTreeOrdering*.
2026-06-04 16:07:12 +02:00
Magne Sjaastad 022d77bef8 macOS: Initial Apple Silicon and x86_64 build support
* Refactor: add MACOSX_BUNDLE option to qt_add_executable in multiple CMakeLists.txt files
* #14045 macOS: Guard std::stacktrace usage and skip ucontext on Apple platforms
* #14045 macOS: Guard std::ispanstream with std::istringstream fallback
* #14045 macOS: Add vcpkg overlay triplets for osx and exclude grpc on osx
* #14045 macOS: CMake macOS build support and openzgy OpenMP-disable patch
* #14045 CI: Add macOS build workflow
* #14045 macOS: Use feature-test macros to detect <stacktrace> and <spanstream>
* #14045 macOS: Make MAX_STIMPLAN_LAYERS constexpr to fix arm64 link error
* #14045 CI: Ship README-macOS.txt with artifact to document Gatekeeper workaround
* #14045 CI: Pin macOS runner to macos-14 and set deployment target to 14.0
* #14045 CI: Move macOS runner to macos-15 and fix README step on configure failure
2026-06-01 12:38:55 +02:00
Kristian Bendiksen 01ceb57323 #14001 Python: Drop hand-written PropertyType, use auto-generated PropertyType
Consolidate the hand-written PropertyType / NNCPropertyType enums in
enums.py into the auto-generated StrEnum classes that already exist in
generated_classes.py. enums.py and all its imports are removed.

The auto-generated class for caf::AppEnum<RiaDefines::ResultCatType>
was named "ResultType" because the existing scriptable m_resultType
fields used keyword "ResultType". Switch those fields to
CAF_PDM_InitScriptableFieldWithScriptKeywordNoDefault, keeping the XML
keyword "ResultType" (so project files still load) but exposing the
script keyword as "PropertyType". The generator now emits a single
PropertyType StrEnum that:

- matches the proto PropertyType for setters (FLOAT/INTEGER aside, the
  members callers actually use are identical),
- gains ALLAN_DIAGRAMS that the C++ side already knew about,
- loses the proto-only REMOVED/UNDEFINED sentinels (unused in any
  Python caller).

rips.NNCPropertyType was exported but unreferenced anywhere — dropped.

Updated Python callers:
- rips.ResultType.X -> rips.PropertyType.X across examples and tests.
- result_type= kwarg / .result_type attribute -> property_type /
  .property_type (the script keyword change renamed those everywhere
  the affected PdmObject fields are accessed from Python).
- view.apply_cell_result's hand-written wrapper now takes property_type
  instead of result_type and forwards via cell_result.property_type.

All 271 Python tests pass, ruff and clang-format clean.
2026-05-26 08:23:28 +02:00
Kristian Bendiksen 8971ebfc9c #14001 Python: Auto-generate StrEnum return types for scriptable methods
Replace the hand-written PropertyDataType wrapper with first-class enum
return support in the code generator. Scriptable methods that derive
from the new caf::PdmEnumObjectMethod<T> template return a typed enum
value across the gRPC boundary; the Python generator emits a StrEnum
class with the texts pulled from the underlying caf::AppEnum<T> and
wraps the call site so callers receive `EnumClass(value)` directly.

caf::PdmDataContainerEnum is the small PdmObject the framework uses to
carry the enum text on the wire (single scriptable QString field).
RimcEclipseCase_propertyDataType becomes declarative: implement
executeEnum() returning the typed RiaDefines::ResultDataType and pick a
returnEnumScriptName() — the base handles serialization and reports
the four AppEnum members (UNKNOWN, FLOAT, DOUBLE, INTEGER) to the
generator.

Drop the hand-written PropertyDataType in enums.py — the generated one
in resinsight_classes is wire-equivalent and now the single source of
truth.
2026-05-26 08:23:28 +02:00
Magne Sjaastad fe59babf21 #13987 PDM: Fix IconProvider operator= clearing pixmap + regression 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.
2026-05-13 14:53:00 +02:00
Magne Sjaastad 92da6633bb #13987 PDM: Add caf::PdmNestedCollection framework
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.
2026-05-13 14:53:00 +02:00
Kristian Bendiksen 21f1330232 #13982 Python: Generate StrEnum classes for AppEnum-typed fields
Auto-generate enum.StrEnum classes from cafPdmPythonGenerator for every
caf::AppEnum-backed scriptable field, deduplicated by C++ AppEnum type.
Generated PdmObject attributes and method arguments now reference the
typed enum (e.g. self.depth_type: DepthType = DepthType.MEASURED_DEPTH)
instead of bare str. Member names are sanitized against Python keywords
and identifier rules (None -> None_, R-G -> R_G).

Existing scripts that pass plain strings keep working because StrEnum
members are strings; the wire format is unchanged.

Bumps python_requires to >=3.11 (StrEnum). Adds an Enum branch in
PdmObjectBase.__convert_to_grpc_value so future IntEnum use is also
handled.
2026-05-13 13:47:40 +02:00
Magne Sjaastad aaa95bdcf3 PdmObjectCollection: Move PdmObject base check to constructor
Replace the class-level static_assert with a DerivedFromPdmObject concept
checked inside the constructor body. The constructor is lazily instantiated,
so T can be forward-declared at the point PdmObjectCollection<T> is used
as a base class.
2026-05-11 13:42:13 +02:00
Kristian Bendiksen 8e6c6e88ba #7142 Janitor: Remove redundant // Overrides comments in command feature headers
The bare "// Overrides" comment is now redundant since the override keyword on
each method already conveys the same information. Qualified comments like
"// Overrides from BaseClass" carry additional information and are kept.
2026-05-11 12:45:21 +02:00
Magne Sjaastad 8005dc772f #13977 Viewer: Fix perspective clipping of very small models
Remove the hard floor against m_defaultPerspectiveNearPlaneDistance
(0.05) when computing the perspective near plane from the closest
bounding-box corner. For very small models the closest corner can sit
within that distance, and clamping pushed the near plane past the
model so it was clipped entirely; parallel projection was unaffected
because its near plane scales directly with the bbox.

The zero/negative guard at the end of the block is the actual safety
net, and the maxFarNearRatio constraint still protects depth-buffer
precision when geometry spans both very close and very distant
corners.
2026-05-08 10:28:00 +02:00
Magne Sjaastad 7fcd192b71 AppEnum: Type-erase the mapping machinery into a non-template base
Move the loops, lookups, and QString machinery out of
AppEnum<T>::EnumMapper into a new non-template AppEnumMapperBase defined
in cafAppEnum.cpp. Each member is now compiled once for the whole
program rather than once per enum type, cutting build time and binary
size for a class template instantiated across hundreds of enums.

AppEnum<T> becomes a thin static_cast shim around the base methods.
Enum values are stored as int in the mapping; a static_assert rejects
enum types whose underlying type is wider than int. The widest
underlying type currently in use in ResInsight is short, so all current
instantiations are unaffected.

Use std::optional<int> for the mapper default value, and assert against
an empty mapping in defaultValue() (the prior code returned m_mapping[0]
unconditionally, which is undefined behavior on empty).

Document why mapper() uses an explicit init flag rather than
std::call_once or a magic-static lambda: setUp() re-enters mapper() via
addItem, so anything that locks on first init would deadlock.
First-access must therefore be single-threaded, as already exercised by
BaseTest.CreateObjectInMultipleThreads.

Add AppEnumTest.MappingRoundTrip covering text <-> enum, index <-> enum,
isValid, and the failure paths of setFromText / setFromIndex (resets to
default, returns false).
2026-05-05 14:27:12 +02:00
Magne Sjaastad 5239a4d378 #13930 Viewer: Guard against empty frustum in per-model culling
Camera::computeViewFrustum() returns an empty Frustum if the projection
matrix is degenerate (e.g., on the first paint after project open, before
a valid near/far has been set). The per-model culling introduced by
82c7172c1 calls Frustum::isOutside() unconditionally, which asserts when
the frustum has fewer than 6 planes. Skip culling when the frustum is
not fully populated; all valid models then contribute to the near/far
calculation, matching the pre-82c7172c1 behaviour.
2026-04-30 21:50:31 +02:00
Magne Sjaastad 29fc0aeaf5 #13806 PdmScripting: Emit hex strings for cvf::Color3f default values
The Python class generator previously emitted cvf::Color3f defaults using
the raw QTextStream operator ("r g b" floats), which is not valid Python
and does not match the hex-string form that scriptable color fields
expect on writeToField.

Convert Color3f defaults to their QColor::name() hex representation and
quote any non-QString value mapped to "str" (e.g. Color3f, caf::FilePath)
so the generated Python is syntactically valid.
2026-04-20 18:55:36 +02:00
Magne Sjaastad bd3836ba25 #13901 ShowPlotData: Invert dependencies via capability mixins and text-dialog signal 2026-04-20 14:09:25 +02:00
Magne Sjaastad 4ae60f1818 Fix GCC warning by specializing PdmVariantEqualImpl for QString 2026-04-14 14:25:41 +02:00
Magne Sjaastad 52329d567d Fix clang issues
* Remove unnecessary message parameter from PdmFieldScriptingCapabilityIOHandler readFromField calls
* Add checks for QFile open operations in BaseTest ReadWrite tests
* Fix integer size assertions in AppEnum and PdmLogging tests
2026-04-10 06:57:52 +02:00
Kristian Bendiksen 7897e41c63 #11371 Remove GLEW dependency and use Qt's QOpenGLFunctions (#13631)
* #11371 Remove GLEW dependency and use Qt's QOpenGLFunctions

Replace embedded GLEW library with Qt's native OpenGL function loading
(QOpenGLFunctions/QOpenGLExtraFunctions) to resolve Qt 6 compatibility
warnings about GLEW conflicts with qopenglfunctions.h.

- Update CVF_CALLSITE_OPENGL macro to provide QOpenGLExtraFunctions pointer
- Replace GLEW initialization with Qt OpenGL context validation
- Keep direct calls for fixed-function GL (glBegin, glEnd, glMatrixMode, etc.)
- Remove glew/ directory containing embedded GLEW source

* #11371 Remove GLU dependency to fix Windows build error

GL/glu.h conflicts with Qt's OpenGL headers on Windows due to APIENTRY
redefinition. Replace gluBuild2DMipmaps with glTexImage2D + glGenerateMipmap,
and gluOrtho2D with glOrtho.
2026-04-09 10:34:15 +02:00
Magne Sjaastad e8223485b1 Fix ADL lookup for cvf pdmToVariant/pdmFromVariant overloads
Move pdmToVariant/pdmFromVariant overloads for cvf::Color3f, Vec3d, Mat4d, and
Mat3d from namespace caf to namespace cvf. Templates in
cafInternalPdmFieldTypeSpecializations.h use "using caf::pdmToVariant" followed
by an unqualified call, so ADL searches the argument's namespace (cvf). With the
overloads only in caf, the default template was selected, causing cvf::Color3f to
be stored raw in a QVariant instead of as QColor — breaking color field editing
and producing QVariant::save warnings.

All call sites now use the unqualified "using caf::pdmXxx; pdmXxx(value)" pattern
so ADL finds the correct overload without depending on cvf:: as a visible prefix.
Add AdlVariantTest to cafPdmCoreColor3fTest.cpp that exercises this exact pattern.

Adds caf::toVariant<T> and caf::fromVariant<T> to cafPdmFieldTraits.h as
thin wrappers that encapsulate the ADL two-step internally. Client code can
now call caf::toVariant(x) directly instead of requiring a using-declaration
at every call site.
2026-04-08 23:12:49 +02:00
Magne Sjaastad 700549fb3b Add baseline compile benchmark results 2026-04-08 12:37:36 +02:00
Magne Sjaastad ab97381d94 Add ADL-based field traits, migrate all call sites, remove cafInternalPdmValueFieldSpecializations.h
Introduce cafPdmFieldTraits.h with ADL-based pdmToVariant/pdmFromVariant/pdmVariantEqual
as a replacement for PdmValueFieldSpecialization. Migrate all types (AppEnum, FilePath,
PdmPointer, cvf types) and all call sites (PdmDataValueField, PdmProxyValueField, UI
framework, ApplicationLibCode). Delete cafInternalPdmValueFieldSpecializations.h.
Add cafPdmFieldTraits unit tests and fix std::optional support.
2026-04-08 12:37:36 +02:00
Magne Sjaastad e0a3606ae1 Add cafPdm_CompileBench target for compile-time benchmarking
Adds an OBJECT library with UNITY_BUILD OFF to measure per-file compile
cost of PDM field types in isolation. Wired into both Fwk/CMakeLists.txt
and the main CMakeLists.txt (under RESINSIGHT_INCLUDE_APPFWK_TESTS).
Also adds build-bench to .gitignore.
2026-04-08 12:37:36 +02:00
Magne Sjaastad f9a081eb87 Migrate more classes to dynamic buttons 2026-03-31 10:52:29 +02:00
Magne Sjaastad 4c57a7271c ProgressInfo: report errors to cafLogger instead of std::cout 2026-03-26 09:59:12 +01:00
Magne Sjaastad 64a7546660 Fix Unity build conflict: remove duplicate PdmObjectCollection from cafPdmObjectGroup
Remove the unused non-template PdmObjectCollection class from cafPdmObjectGroup.h/.cpp.
This class conflicted with the template caf::PdmObjectCollection<T> in cafPdmObjectCollection.h,
causing MSVC redefinition errors in Unity builds. The class was dead code with no usages
in application code.

Also correct forward declarations in test MainWindow headers from PdmObjectCollection
to PdmObjectGroup, matching actual usage in the .cpp files.
2026-03-21 17:24:22 +01:00
Magne Sjaastad 6dbc16c5e6 cafTestApplication: Add console logging support
Registers a ConsoleLogger to handle PDM logging output and removes manual std::cout calls from test PDM objects in favor of the framework's logging system.
2026-03-19 16:22:17 +01:00
Magne Sjaastad 4dceac69dc cafTestApplication: Move PDM object classes into PdmObjects subfolder 2026-03-19 16:22:17 +01:00
Magne Sjaastad 26a2861d56 cafUserInterface: Skip size_t editor registration on 64-bit Windows where it duplicates quint64 2026-03-19 16:22:17 +01:00
Magne Sjaastad 04ca172893 PdmObjectHandle: Add createDerivedObjectsRecursively() lifecycle hook
Add createDerivedObjectsRecursively() which traverses the object tree using
direct recursion and calls the virtual createDerivedObjects() on each node.
Called between the two resolveReferencesRecursively() passes in RiaApplication,
allowing objects to create child objects based on already-resolved ptr fields.
The second resolve pass then handles references in the newly created children.
2026-03-19 15:10:26 +01:00
Magne Sjaastad 2bf51950e4 cafCmdFeatureManager: log and stop with clear message for unknown command feature
Use CAF_PDM_LOG_ERROR and qFatal to notify the developer with an actionable
message when a command feature ID is not registered in the factory. This
replaces the silent CAF_ASSERT and makes it clear that the feature may have
been deleted without removing all references in appendMenuItems().
2026-03-16 09:19:15 +01:00
Magne Sjaastad 82c7172c1a Viewer: Improve near/far clipping plane calculation
Iterate per-model bounding boxes and skip models outside the camera frustum to prevent distant off-screen objects from inflating the far plane. This improves depth buffer precision and reduces z-fighting.

Enforce a maximum far/near ratio of 3000.0 by pushing the near plane forward if necessary. Additionally, refine the near plane adjustment when zooming into a point of interest to prevent geometry clipping.
2026-03-16 09:02:41 +01:00