Commit Graph
1243 Commits
Author SHA1 Message Date
Kristian Bendiksen 5674130504 #12720 Histogram: Recreate summary vector curves when dropping an ensemble
When an ensemble is dropped on a histogram plot showing summary vector curves,
create a new curve per distinct vector and time step for the dropped ensemble,
matching the existing behavior for ensemble parameter curves.
2026-08-13 07:19:18 +02:00
Jørgen Herje 5afb5c8a17 Sumo summary data using ri-cloud-api (#14503)
- Fetch SUMO summary data using ri-cloud-api
- Update ri-cloud-api submodule to get improved speed on sumo search
2026-08-12 12:22:40 +02:00
Magne Sjaastad 1660e333ff #14493 Delete curves for all cases in one pass when deleting a summary ensemble
deleteSummaryCaseCollection() looped over every case in the ensemble, and for each case scanned every summary plot and called updateConnectedEditors() on every multi plot. For an ensemble with many realizations this scanned each plot once per realization, and updated the connected editors once per realization and multi plot. This showed up as a hot spot in the profiler.

Replace deleteCurvesAssosiatedWithCase() with deleteCurvesAssosiatedWithCases(), which takes a set of cases and returns whether anything was deleted. Each plot is now scanned once, and the connected editors of a multi plot are updated only when that multi plot actually lost a curve.

RicCloseSummaryCaseFeature and RicCloseObservedDataFeature are updated to the new signature. RicCloseSummaryCaseFeature also scans each plot once instead of once per case.
2026-08-10 12:38:41 +02:00
Magne Sjaastad 2237f578c8 #14486 Contour Map: Always use an available cell result as data source
A new contour map created from the right-click menu on a case used a hardcoded SOIL result, resulting in an empty view when SOIL was not present in the case. Use the cell result of an existing view for the same case if one is available, and otherwise fall back to RigCaseCellResultsData::defaultResult(), which verifies that the result exists before selecting it. Completion Type is a category result and is now excluded as a default result for both 3d views and contour maps.
2026-08-10 12:38:21 +02:00
Magne Sjaastad b851801cfb #14488 Surface and intersection improvements
Use I as the default direction when creating an IJK intersection, and center the fixed index on the I axis.

Allow multiselect of surfaces for a Surface Curve. The field keyword is changed from Surface1 to Surfaces, with a keyword alias so existing project files are read as before. One curve is drawn per selected surface, each with its own label and color.

Use the color defined in the Surfaces collection for Surface Band and Surface Curve. The color is shown as read only, and a Custom Color option allows the user to specify a color. Bands created from an ensemble surface keep the structural uncertainty colors, as the statistics surfaces share the same color.
2026-08-10 12:38:02 +02:00
Magne Sjaastad 240df658ee Guard against missing RFT reader when creating an RFT curve
addRftCurve() selects the first Eclipse result case in the project without
checking that it has an RFT reader, and then dereferences rftReader(). The
command is enabled by hasRftData(), which returns true if any case has a
reader, so with several Eclipse cases loaded an enabled menu entry can select
a case with no RFT data and crash.

Null check the reader before use, matching the guard already used by
hasRftData() and hasRftDataForWell().
2026-08-10 10:07:32 +02:00
Magne Sjaastad c0ebe1a331 #14496 MSW export: Order COMPSEGS by branch number
The COMPSEGS rows were emitted in the order the branches are listed in, so they followed the WELSEGS order where the completion branches come before the laterals with a lower branch number.

The rows are now collected while the segments are visited and sorted by branch number before they are added. The sort is stable, so the rows of a branch keep their order along the well path.
2026-08-10 09:42:17 +02:00
Magne Sjaastad f796801a7a #14496 MSW export: Assign branch ID to well path laterals before completions
Branch numbers are handed out from two counters. The well path laterals are numbered first, so that the main bore and the laterals occupy the lowest branch numbers. The completion branches (valves, fractures and fishbones) are numbered after all laterals, and are still listed immediately after the lateral they are connected to.

The multiple_laterals test project is reduced to a single Eclipse case, and is used by two new unit tests covering the branch numbers and the order the branches are listed in.
2026-08-10 09:42:17 +02:00
Magne Sjaastad c8e11da3d5 #14252 MSW: Report a grid cell only once in COMPSEGS
When several perforation intervals overlap the same grid cell, the main bore COMPSEGS table emitted one row per interval. Two perforations placed back to back therefore reported the same IJK twice, while COMPDAT correctly reported a single connection for that cell.

The candidate intersections collected for one cell all describe the same IJK, so they are now merged into a single COMPSEGS row spanning the union of the overlapping measured depth ranges.

Add TestModels/msw-export/project-files/perf_two_back_to_back.rsp covering the case.
2026-08-10 09:41:41 +02:00
Magne Sjaastad 94da54c4f5 Remove AsyncPdmObjectVectorDeleter and delete PDM objects synchronously
Deleting PDM objects on a worker thread is not safe. PdmObjectHandle::prepareForDelete()
mutates state owned by other objects, it nulls the guarded pointers held by other objects
and clears m_pointersReferencingMe, an unsynchronised std::set that every PdmPointer
construction and destruction touches. Destroying an object off the main thread therefore
races with the main thread on the shared object graph. See issue 14491.

Profiling a summary ensemble teardown shows the mechanism does not pay for itself. Releasing
397 Drogon realizations takes 0.24 s sequentially and 0.24 s in parallel, and for a heavy
case the parallel release is slower than the sequential one, because free() is serialised
inside the allocator. The PDM bookkeeping itself is 0.4 to 2.8 percent of the teardown.

Remove the class and deleteChildrenAsync(), and delete synchronously instead. The call sites
that used clearWithoutDelete() and a manual delete loop to work around the race can now call
deleteChildren() directly. Add caf::PdmObjectHandleTools::deleteObjects() for the case where
the objects are no longer owned by a child array field.

The observer disconnection from issue 12262 does not depend on clearWithoutDelete(). ~Signal()
unregisters itself from every observer, so a deleted child detaches itself. That fix addressed
the async race, where ~Signal() mutated the observer list from a worker thread. The unit test
is updated to assert the observed signal count directly instead of relying on a crash.
2026-08-10 09:40:33 +02:00
Magne Sjaastad 1c4c304064 #14476 ApplicationLibCode: Remove unused cvf includes
Remove 95 cvf include lines that the including file does not use. Found by
extracting the symbols declared by every VizFwk header, including symbols they
re-export, and flagging includes where none of those symbols appear anywhere in
the file. Each removal is verified by a full build.

Most of them are cvfVector3.h and cvfObject.h, left behind as the files they
were once needed by changed.

pch.h is left untouched. It includes cvfObject.h and cvfVector3.h on purpose, so
that the files using the precompiled header do not have to.

Note that a clean build after removing an include does not prove the include was
unnecessary, only that the declarations still arrive some other way. That path
can differ between platforms and with RESINSIGHT_ENABLE_UNITY_BUILD, so this
needs a CI round on Linux as well.
2026-08-07 15:05:57 +02:00
Magne Sjaastad 0a4bebcd41 #14476 ApplicationLibCode: Remove includes of cvfBase.h
cvfBase.h includes cvfAssert.h, so these six files were the last indirect route
into the assert header that the previous commit removed from ApplicationLibCode.

Five files dropped the include with no further change. RimSeismicAlphaMapper
declared alphaValue as returning cvf::ubyte, a typedef defined in cvfBase.h
itself, so no smaller VizFwk header provides it. Since cvf::ubyte is
unsigned char, use that directly in the declaration, the definition and the
cast. The type is identical, so callers are unaffected, and the class no longer
depends on VizFwk at all.
2026-08-07 15:05:57 +02:00
Magne Sjaastad 56e98ba1c4 #14476 ApplicationLibCode: Replace CVF_ASSERT with CAF_ASSERT
Migrate all assert macros in ApplicationLibCode to CAF_ASSERT and remove every
use of cvfAssert.h.

CVF_ASSERT is replaced one to one. CVF_TIGHT_ASSERT is also replaced by
CAF_ASSERT, which is semantically exact: CVF_ENABLE_TIGHT_ASSERTS is 1 only
under _DEBUG, and that is what CAF_ASSERT now does. The two CVF_FAIL_MSG sites
become CAF_ASSERT( false && "message" ), preserving the message with the idiom
already used elsewhere in the code base.

Counts before and after: CVF_ASSERT 1044 to 0, CVF_TIGHT_ASSERT 66 to 0,
CVF_FAIL_MSG 2 to 0, cvfAssert.h references 154 to 0.

Include handling: files that included cvfAssert.h directly now include
cafAssert.h instead, includes left dead by the migration are removed, and files
that were relying on cvfAssert.h transitively get an explicit cafAssert.h. Files
that reach cafAssert.h through another caf header are left unchanged; a missing
include here is a compile error, not a silently disabled assert.

ResultStatisticsCache links only LibCore and therefore had no path to
cafAssert.h. Add the cafPdmCore directory as a private include path rather than
linking the library, since cafAssert.h is header only.

Note that this stops these asserts from firing in Release and RelWithDebInfo,
where CVF_ASSERT was previously active.
2026-08-07 15:05:57 +02:00
Magne Sjaastad 827fa64deb #14252 MSW: Name the lateral in the WELSEGS comment line
The first segment of a lateral had its comment cleared when the lateral had a tie-in valve, leaving the rows unlabelled. Write the well path name instead, so the exported segments can be traced back to the lateral they belong to.
2026-08-07 13:29:32 +02:00
Magne Sjaastad 74a6c0827b #14477 MSW: Apply max segment length to fishbones laterals
The geometry path emitted one WELSEGS row per cell intersection of a fishbones lateral, ignoring the max segment length and the custom segment intervals. The tree path split them like every other completion, in collectCompletionWelsegsSegments.

Split each cell intersection with createSubSegmentMDPairs and chain the resulting rows. The lateral geometry is not part of the well path, so the TVD of a sub-segment cannot be interpolated along the well path. Interpolate linearly between the start and end TVD of the intersection instead, as the tree path did for fishbones. The cell is connected by the first sub-segment only, leaving COMPSEGS unchanged, and the lateral label stays on the first row.

An intersection now covers several segment numbers that share one effective diameter, and must still contribute once to the sum for its cell. FishbonesLateralSegment therefore holds the segment numbers of an intersection rather than a single one, and the intersections are grouped per lateral in FishbonesLateral. This replaces the separate list of first and second segment numbers, since the reduction rule is now expressed on the intersections of a lateral.

Verified with a copy of fishbones.rsp with max segment length enforced at 4 m: the three laterals are split into three or four rows each, depths are evenly interpolated, effective diameters are unchanged at 0.01664 and 0.00960, and COMPSEGS is identical. The sweep against TestModels/msw-export is unchanged, as none of the projects enforce a max segment length.
2026-08-07 13:29:32 +02:00
Magne Sjaastad 32850cac9e #14477 MSW: Make the ICD area summation order independent
The summation reproduced the tree implementation, where an ICD sub connected to several cells took part in the sum of each of them, reading areas that earlier cells had already replaced. The result depended on the order the cells were visited in, and an ICD sub could contribute an already combined area to the next cell.

Compute every cell sum from the original areas instead. An ICD sub spans a 0.1 m valve segment and normally connects to a single cell, and when it reaches into more than one it now reports the largest of the sums it takes part in.

Behaviour is unchanged for the common case of one ICD sub per cell, and the sweep against TestModels/msw-export is unaffected. Added tests for the multi-cell case and for independence of the recording order.
2026-08-07 13:29:32 +02:00
Magne Sjaastad cd315870f2 #14477 MSW: Sum WSEGVALV area for fishbones ICD subs sharing a grid cell
The legacy tree path gave every fishbones ICD sub connected to the same grid cell the sum of their areas, so the cell sees the total flow area of the ICDs completing it. That was part of updateDataForMultipleItemsInSameGridCell and disappeared with the rest of the tree code, leaving each ICD sub with its own area.

Record the grid cells each ICD sub connects to while the branches are built, and apply the summation together with the effective diameters. FishbonesDiameterContext now carries both, and is renamed to FishbonesExportContext.

An ICD sub connected to several cells takes part in the sum of each of them and ends up with the value of the last cell in ascending cell order. This is order dependent, and is kept because the tree implementation behaved the same way.

None of the projects in TestModels/msw-export has more than one ICD sub per cell, so the sweep against the stored reference output is unchanged. Added unit tests for applyIcdAreaPerCell and applyEffectiveDiameters instead, since neither function had coverage.
2026-08-07 13:29:32 +02:00
Magne Sjaastad a4713ed43b #14477 MSW: Compute effective diameter for fishbones laterals
The geometry path exported the raw equivalent diameter for every fishbones lateral segment. The legacy tree path replaced it with an effective diameter, computed in updateDataForMultipleItemsInSameGridCell, which was removed together with the rest of the tree code.

Reinstate both rules. Laterals sharing a grid cell get Deff = sqrt(d1^2 + d2^2 + ..) over the lateral segments in that cell (#7686). The first segment of a lateral shares its cell with the main bore and with the first segment of every other lateral on the same sub, so it inherits the effective diameter of the second segment of the same lateral (#7731). A lateral contained in a single grid cell has no second segment and keeps the combined value, which is where the difference from the tree path was most visible.

Lateral segments are recorded while the branches are built, since the grid cell of a segment is not recoverable afterwards. COMPSEGS deduplication clears the cell intersections of segments in an already connected cell. The context is shared by the main bore and all tie-in laterals, and applied once the branches are assembled.

Verified against the twelve projects in TestModels/msw-export: every well with stored reference output now matches the legacy values, including the fishbones laterals that previously differed.
2026-08-07 13:29:32 +02:00
Magne Sjaastad c3801b268e #14477 MSW: Restore diameter and roughness for fishbones ICD subs
The fishbones ICD sub segment left RigMswSegment::diameter and roughness unset, and the formatter renders an empty optional as the 1* default marker. The legacy tree path emitted 0.15 and 5.0e-5 for these rows, taken from the RicMswSegment constructor defaults. RigMswSegment has never had such defaults, so the comment claiming the tree behaviour was matched was wrong.

Set both values explicitly, as buildFractureBranches already does. Verified against TestModels/msw-export/project-files/fishbones.rsp: the ICD sub WELSEGS row again exports 0.15000 and 0.0000500, matching the stored legacy reference output.
2026-08-07 13:29:32 +02:00
Magne Sjaastad 593f27dcf4 Guard against null case and view when painting overlay and creating intersections
Four crashes reported from release builds share the same shape: a pointer that
is null during teardown or before a view is fully created is dereferenced
without a check.

RiuViewer::paintOverlayItems() used the owner case of the view and of the
comparison view without checking it, and dereferenced the result of a
dynamic_cast directly. The owner case is null while a case is being closed.

RicIntersectionFeatureImpl::createIntersectionBoxSlize() checked
activeMainOrComparisonGridView() but dereferenced activeGridView(), which is a
different object and can be null or have no viewer.

RimEclipseContourMapView::onCreateDisplayModel() called viewer()->mainCamera()
before the viewer exists.

RimCorrelationPlotCollection::applyFirstEnsembleFieldAddressesToPlot() called
front() on the ensemble parameter vector, which is empty for an ensemble
without realization parameters.
2026-08-07 12:21:41 +02:00
Magne Sjaastad ebf75c09a1 #14411 Enforce name uniqueness for surfaces, polygons and folders
* #14411 Enforce name uniqueness for surfaces, polygons and folders

Names must be unique among siblings sharing the same parent folder. Items in different folders may keep identical names, and comparison is case sensitive.

Siblings are the objects held by the same caf::PdmChildArrayField. Items and folders live in two distinct child arrays in caf::PdmNestedCollection, so a folder and an item may share a name under the same parent.

The Python API gets an OnNameConflict flag on AddFolder, CreatePolygon, ImportSurface and NewRegularSurface, supporting FAIL (default), AUTO_RENAME and OVERWRITE. NewSurface is left out, as grid case surfaces derive their tree label from the case and K index and carry no name of their own.
2026-08-07 08:34:58 +02:00
Magne Sjaastad 5e791353b2 #14470 Do not truncate folder names containing a dot when removing file extension
The ensemble file set removed the file extension by searching for the last dot in the complete path. When the path pattern was already without extension, the last dot was found in a folder name, truncating the path pattern and causing the search for SMSPEC files to fail.

Add RiaFilePathTools::removeFileExtension based on std::filesystem::path::replace_extension, and use it both in RimEnsembleFileSet and in the grid and summary ensemble import, replacing a duplicated lambda doing the same operation.
2026-08-06 14:10:49 +02:00
Magne Sjaastad 0012a65922 #14436 Surface intersection curves and bands for Intersection Box and I/J/K Intersection
* Add RivSurfaceIntersectionCurveTools for shared surface intersection curve geometry
* Move the surface intersection collection to RimIntersection
* Add surface curtain footprints for the box and i/j/k intersections
* Build surface intersection curves for the box and i/j/k intersections
* Follow the pillar tilt when projecting a surface onto an intersection
* Estimate the surface intersection by continuing the pillar past the curtain
2026-08-06 08:06:53 +02:00
Kristian Bendiksen d87a0d3048 Refactor RifFormationNamesReader to return std::expected
Replace the QString* errorMessage out-parameter with std::expected<RigFormationNames, QString> in RifFormationNamesReader, and propagate the pattern to RimFormationNames::readFormationNamesFile() which now returns std::expected<void, QString>.

Fatal errors (file cannot be opened, FMU line-parse failure) return std::unexpected. Malformed .lyr lines are still skipped so the rest of the file loads, with warnings logged via RiaLogging instead of collected in the out-parameter. RimFormationNamesCollection::readAllFormationNames() now logs errors it previously discarded.
2026-08-05 16:03:42 +02:00
Magne Sjaastad 1aa95936fc #14362 Allow arbitrary Z-scale factor
Make the Z-scale combo boxes in the toolbar and property editor editable, so any positive scale value can be entered as text. Invalid input is rejected and the previous value is restored.

Add keyboard shortcuts Ctrl+Shift+Up and Ctrl+Shift+Down to step the Z-scale of the active view through the predefined scale values.
2026-08-04 12:50:34 +02:00
Magne Sjaastad 9ccca3e20a #14401 Introduce initAfterInsert() to combine resolveReferencesRecursively() and initAfterReadRecursively() 2026-08-03 15:34:10 +02:00
Magne Sjaastad 42aa580192 #14426 Export multiple surface properties to IRAP/GRI
Add a multi-select list of values to export in the export dialog, containing the surface depth and the properties available on the selected surfaces. IRAP/GRI files hold a single value per node, so each selected value is written to a separate file named <surface>--<value>. Exporting depth only keeps the plain surface name.

Property values are exported without resampling and require a regular surface with matching Nx and Ny. Values that cannot be exported are reported as warnings.

The export grid defaults are no longer rounded when they originate from a regular surface, and the grid rotation is added to the dialog. Both are required to export the surface without resampling.
2026-07-31 13:54:54 +02:00
Magne Sjaastad d48ecbdcdf #14426 Remember last used export folder when exporting surface to IRAP/GRI
The export folder was only applied to the dialog when a single regular surface was selected. Always seed the folder from the last used EXPORT_SURFACE directory by splitting setDefaults() into setExportFolder() and setGridDefaults().

A single non-regular surface now also falls into the bounding box estimation branch instead of keeping the 10x10 field defaults.
2026-07-31 13:54:54 +02:00
Magne Sjaastad f9c881e442 #14343 Add context menu for toggling selected cases in ensemble import dialog 2026-07-29 15:17:05 +02:00
Magne Sjaastad febea598dc #14379 Guard against missing intersection view in Show 2D Intersection View 2026-07-28 13:02:18 +02:00
Magne Sjaastad 4a06edea28 #14372 Resolve references when creating contour map from 3D view 2026-07-28 11:35:58 +02:00
Kristian Bendiksen 280763f4c0 #14203 Add cumulative curve option to Grid Statistics plot
A new "Show Cumulative Curve" checkbox on the grid statistics data source adds a cumulative curve on the right axis, in addition to the regular histogram curve. The cumulative curve shares the data source of its non-cumulative counterpart and follows all changes to it. The cumulative sum works with all frequency types and both graph types.

Remove the legacy Grid Statistics dialog (RicGridStatisticsDialog) and its context menu command, which provided the previous cumulative display.
2026-07-27 12:37:59 +02:00
Kristian Bendiksen 5dc3374733 #14226 intersection along ijk axis
* #14226 Add intersection along i/j/k axis

Add a new persistent intersection type that follows the grid pillars at a
fixed i, j or k index. Unlike the axis-aligned intersection box, the surface
is built from the grid cell faces and therefore steps along faults and curved
pillars, which is useful for structural restoration analysis.

The user selects the axis, the fixed index, the two perpendicular index
ranges and which cell face (front/back pillar) to use. The geometry generator
emits the chosen cell face of every cell in the index plane directly from the
native pillar corners, so cell result colors map exactly.

The feature is available from the Intersections context menu for Eclipse
views and supports 3D-view picking and cell result readout.
2026-07-27 11:21:05 +02:00
Magne Sjaastad 2ac1948abe #14245 Remove gsl functions and ThirdParty/gsl folder 2026-06-24 18:47:04 +02:00
JJ 82aa009378 Dock system selection improvements and fixes (#14305)
* Make sure we don't trigger another select when a view in the project tree is selected.
* Fix for #14255 and related issues
* Make sure we can close and open a main window, keeping the layout when reopened.
2026-06-24 16:07:21 +02:00
Magne Sjaastad 81f1aca0ba #14277 Hide property filter insert when not a collection child 2026-06-23 07:31:39 +02:00
Magne Sjaastad 3ae102ba6c #14241 MSW: Use valve segment MD for ICV COMPSEGS distances
ICV valve COMPSEGS rows used the cell overlap MD range within the valve coverage instead of the valve segment measured depth. The legacy tree export redirected the perforation intersections onto the ICV segment, so their COMPSEGS Start/End Length reflected the valve segment MD range. Restore that behavior by emitting the ICV COMPSEGS with the valve segment MD range while still selecting the overlapping cells. Fixes test_well_events test_wells_only_appear_at_their_event_dates.
2026-06-19 12:50:14 +02:00
Magne Sjaastad f4a7d2cb4a #14241 MSW: Fix dual-porosity perforation COMPSEGS over-reporting
The geometry-based MSW export emitted a COMPSEGS row for every cell a perforation overlaps in the whole-well geometric intersection. In dual-porosity models this splits a perforation across matrix cells at cell boundaries, producing extra connections that do not match the COMPDAT export. Restrict main-bore perforation COMPSEGS to the cells the perforation actually connects to, computed by clipping the well path to the perforation MD range and re-intersecting the grid, mirroring generatePerforationsCompdatValues. For single-porosity models the cell sets are identical, so this is a no-op.
2026-06-19 12:50:14 +02:00
Magne Sjaastad 3c5c160b93 #14241 MSW: Drop redundant FromGeometry suffix from branch builders
With the legacy tree-based path removed there is only one MSW branch construction approach, so the FromGeometry suffix is no longer needed. Rename buildMainBoreBranchFromGeometry, buildValveBranchesFromGeometry, buildFractureBranchesFromGeometry and buildFishbonesBranchesFromGeometry accordingly, and update the architecture diagrams.
2026-06-19 12:50:14 +02:00
Magne Sjaastad 3e0d2e22ff #14241 MSW: Remove obsolete TODO in buildMswWellExportData
The geometry-based MSW export now handles valve completions, fishbones laterals, fractures and tie-in laterals, so the comment describing these as unimplemented is no longer accurate.
2026-06-19 12:50:14 +02:00
Magne Sjaastad 5afdeac106 #14241 MSW: Update stale comments referencing deleted legacy classes
Remove references to the deleted RicMswItem/RicMswBranch/RicMswSegment tree and the removed collectWelsegsData collection functions from code comments in the geometry-based MSW export path.
2026-06-19 12:50:14 +02:00
Magne Sjaastad 313ed1e4fc #14241 MSW: Remove obsolete legacy MSW code and data structures
Remove the legacy tree-based MSW extraction path now that the geometry-based path is the only supported implementation. This deletes extractSingleWellMsw_Legacy and all unused tree-building helpers in RicWellPathExportMswTableData, trims RicMswTableDataTools to the shared helpers used by the geometry path, and removes the RicMswItem class family (RicMswBranch, RicMswSegment, RicMswCompletions, RicMswExportInfo, RicMswSegmentCellIntersection, RicMswValveAccumulators).

Also remove the useImprovedMswDataStructures preference and its keyword, and delete the obsolete legacy-vs-geometry comparison unit test.
2026-06-19 12:50:14 +02:00
JJ b187bf85a7 Add context menu to empty plot window area (#14243)
* Add context menu to empty plot window area
Improve drag'n'drop into empty plot window area
2026-06-19 09:25:33 +02:00
Jon Jenssen 0973dfd62b Some cleanup 2026-06-17 13:55:32 +02:00
Jon Jenssen 18cf162ce0 Some cleanup 2026-06-17 13:55:32 +02:00
jonjenssen 44488996f3 Clean up PDF snapshots a bit 2026-06-17 13:55:32 +02:00
jonjenssen 52df6fd283 Snapshot work in progress 2026-06-17 13:55:32 +02:00
Jon Jenssen 361b4bc3db Work in progress: Support capturing snapshots with a given size. 2026-06-17 13:55:32 +02:00
Jon Jenssen 9823f9c5a3 Update to latest qt adv docking version
Make sure copied 3d or plot views get a unique id
2026-06-17 13:55:32 +02:00
Jon Jenssen a1fe3739d1 Remove last traces of MDI 2026-06-17 13:55:32 +02:00