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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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.
* 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
* #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.
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.
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.
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.
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.
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.
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.
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().
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.
Add isOnGuiThread() helper and dispatch each static update method to
the GUI thread via QMetaObject::invokeMethod when called from a worker
thread. start()/finished() use BlockingQueuedConnection to ensure
stack integrity; description/progress updates use QueuedConnection.
Also prevent multiple overlapping dialogs by only reparenting the
progress dialog when no operation is active.
The following text was seen on Ubuntu 20.24, and the text disappears after this commit:
"QObject::disconnect: wildcard call disconnects from destroyed signal of QComboBox::unnamed
QObject::disconnect: wildcard call disconnects from destroyed signal of QSlider::unnamed"
Add fillWidth() to PdmUiButton to allow buttons to expand horizontally
instead of sizing to content. Make createButton protected so subclasses
can reuse button creation logic.
Remove custom editor attribute classes and migrate all double field validation and formatting (range, decimals, number format) to the attribute map system. Refactor PdmUiDoubleValueEditor to read settings from the field's attributes and always display formatted values. Remove redundant defineEditorAttribute overrides. Add tests for pair<bool, double> field validation. Centralize and simplify double field UI configuration for improved maintainability.
Added a compile-time check to call clampValue on fields that support it before setting values from the UI. This ensures values are clamped to valid limits automatically when applicable.
- Use 'g' format with precision for AUTO in valueToText
- Remove sprintfFormat function and its declaration
- Replace individual tests with a single parameterized test
- Expand test coverage for all formats and precisions
Enhance validation error tooltip handling by introducing a 100 ms delay before display to prevent premature dismissal from key events. Ensure tooltips are shown at the correct widget position and only when visible. Also, improve removal of error icons and support for composite editor widgets. These changes make error feedback more consistent and user-friendly.
* Add support for custom validation callbacks on fields
Introduce setCustomValidationCallback to PdmFieldHandle, allowing custom validation logic via user-provided lambdas or functions. The validate() method now invokes this callback if set, in addition to built-in checks. Includes comprehensive unit tests for custom and combined validation scenarios. Backward compatible: default behavior unchanged if no callback is set.
* Update QMinimizePanel to use standard Qt expand/collapse icons
Replaced custom expand/collapse icons with standard Qt style icons for better platform consistency. Improved title bar layout by increasing right margin, vertically centering the title label, and updating the collapse button styling for a cleaner appearance and subtle hover effect.
Enhanced parsing in PdmFieldScriptingCapabilityIOHandler to correctly handle backslashes and escape sequences in both quoted and unquoted strings. Unquoted Windows paths now preserve backslashes, while quoted strings process escape sequences as expected. Added unit tests to verify correct handling of both cases.
Add tests for Windows-style path handling in rips API
Introduce test_windows_paths.py with two pytest tests to verify correct handling of Windows-style file paths (backslashes) in the rips Python API.
Removed manual setAlignment(Qt::AlignRight) calls for UI buttons,
as PdmUiButton now defaults to right alignment. Also removed
unused cafPdmUiButton.h includes from several files.
* Simplifies PdmUiFieldSpecialization implementation.
Refactors the PdmUiFieldSpecialization implementation to reduce code duplication.
Introduces a base class `PdmUiFieldSpecializationForValueSpec` that delegates to `PdmValueFieldSpecialization`, avoiding boilerplate code for common types.
The primary template now inherits from the new base class, providing default behavior for types with custom `PdmValueFieldSpecialization`.
* Improve AppEnum subset handling to avoid key collisions
Refactored AppEnum to use a unique key combining owner class name and field keyword for enum subset storage, preventing collisions when different object types use the same field keyword. Updated setEnumSubset and enumSubset to accept PdmFieldHandle pointers. Added tests to verify correct and independent subset behavior across object types and handle edge cases.
* Refactor PdmValueFieldSpecialization with base helpers
Introduce base classes for default isEqual and QVariant conversion. Update specializations to inherit from these helpers, removing redundant code and centralizing default behaviors.
- Handle empty arrays [] in std::vector<cvf::Vec3d> parser
- Only treat ReadCorruptData as error in generic template (ReadPastEnd
is expected for types like caf::FilePath that consume all input)
- Use strict mode (allowExtraCharacters=false) for Python GRPC parsing
Fixes cafPdmScripting_UnitTests::PdmFieldSerialization.OptionalValues test
failure where empty input for std::optional<int> and std::optional<double>
fields was incorrectly set to default values (0) instead of remaining unset.
Problem:
- Optional handler used error count to determine parsing success
- Empty stream reads set value to 0 but didn't add errors (only checked ReadCorruptData)
- Result: optional fields set to 0 instead of remaining unset
Solution:
- Modified optional handler to check for empty input before parsing
- Empty input now correctly leaves optional field unset (no error)
- Maintains strict validation for invalid input (adds error, resets optional)
Changes:
- PdmFieldScriptingCapabilityIOHandler<std::optional<T>>: Check atEnd() before parsing
- int/double handlers: Only call checkForExtraCharactersAfterValue() on success
Testing:
- All cafPdmScripting_UnitTests pass (8/8)
- All test_pdmobject_validation.py tests pass (10/10)
- Optional double fields no longer generate spurious validation errors