From 05aceef9364d4c57cf326da4e5b632ec71b59c73 Mon Sep 17 00:00:00 2001 From: jonjenssen <69144954+jonjenssen@users.noreply.github.com> Date: Tue, 26 Jan 2021 13:08:21 +0100 Subject: [PATCH] Polygonfilter updates2 (#7286) * Make sure all contourmap copies are getting the correct case set for cell filters when creating/copying maps. * Rewrite polyline part manager to be more generic, not just linked to annotations. * Add new partmgr for cell filters to draw polygon filter outlines in both eclipse and geomech views * Show lines/spheres for polygon filter outline * Add color edit for line and spheres * Add support for z plane lock in poygon filter outline * Add new flags for enabling filter and/or polyline display * Add K range filter to polygon filter * Enable picking automatically when creating a new polygon filter --- .../Commands/RicNewContourMapViewFeature.cpp | 3 + .../ModelVisualization/CMakeLists_files.cmake | 6 +- .../RivAnnotationsPartMgr.cpp | 8 +- .../RivAnnotationsPartMgr.h | 7 +- .../RivCellFilterPartMgr.cpp | 89 ++++++ .../ModelVisualization/RivCellFilterPartMgr.h | 60 ++++ .../RivMeasurementPartMgr.cpp | 6 - .../RivPolylineAnnotationPartMgr.cpp | 285 ------------------ .../ModelVisualization/RivPolylinePartMgr.cpp | 274 +++++++++++++++++ ...notationPartMgr.h => RivPolylinePartMgr.h} | 37 +-- .../RimPolylinesAnnotationInView.cpp | 21 ++ .../RimPolylinesAnnotationInView.h | 6 +- .../RimPolylinesFromFileAnnotation.cpp | 5 + .../RimUserDefinedPolylinesAnnotation.cpp | 7 +- .../ProjectDataModel/CMakeLists_files.cmake | 1 + .../CellFilters/CMakeLists_files.cmake | 2 + .../CellFilters/RimCellFilter.cpp | 13 +- .../CellFilters/RimCellFilter.h | 2 + .../CellFilters/RimCellFilterCollection.cpp | 22 +- .../CellFilters/RimCellFilterCollection.h | 2 + .../CellFilters/RimCellFilterIntervalTool.cpp | 125 ++++++++ .../CellFilters/RimCellFilterIntervalTool.h | 55 ++++ .../CellFilters/RimPolygonFilter.cpp | 235 ++++++++++++++- .../CellFilters/RimPolygonFilter.h | 27 +- .../ProjectDataModel/Rim3dView.cpp | 41 ++- .../ProjectDataModel/Rim3dView.h | 4 + .../ProjectDataModel/RimEclipseView.cpp | 1 + .../ProjectDataModel/RimGeoMechView.cpp | 1 + .../RimPolylinesDataInterface.h | 29 ++ .../ProjectDataModel/RimViewController.cpp | 2 + .../ReservoirDataModel/RigPolyLinesData.cpp | 153 +++++++++- .../ReservoirDataModel/RigPolyLinesData.h | 37 ++- 32 files changed, 1218 insertions(+), 348 deletions(-) create mode 100644 ApplicationLibCode/ModelVisualization/RivCellFilterPartMgr.cpp create mode 100644 ApplicationLibCode/ModelVisualization/RivCellFilterPartMgr.h delete mode 100644 ApplicationLibCode/ModelVisualization/RivPolylineAnnotationPartMgr.cpp create mode 100644 ApplicationLibCode/ModelVisualization/RivPolylinePartMgr.cpp rename ApplicationLibCode/ModelVisualization/{RivPolylineAnnotationPartMgr.h => RivPolylinePartMgr.h} (53%) create mode 100644 ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterIntervalTool.cpp create mode 100644 ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterIntervalTool.h create mode 100644 ApplicationLibCode/ProjectDataModel/RimPolylinesDataInterface.h diff --git a/ApplicationLibCode/Commands/RicNewContourMapViewFeature.cpp b/ApplicationLibCode/Commands/RicNewContourMapViewFeature.cpp index 7d042be921..f3d5ca2920 100644 --- a/ApplicationLibCode/Commands/RicNewContourMapViewFeature.cpp +++ b/ApplicationLibCode/Commands/RicNewContourMapViewFeature.cpp @@ -36,6 +36,7 @@ #include "RimGeoMechView.h" #include "RimRegularLegendConfig.h" +#include "RimCellFilterCollection.h" #include "RimFaultInViewCollection.h" #include "RimSimWellInViewCollection.h" #include "RimSurfaceInViewCollection.h" @@ -127,6 +128,7 @@ void RicNewContourMapViewFeature::onActionTriggered( bool isChecked ) if ( eclipseCase ) { eclipseCase->updateConnectedEditors(); + eclipseContourMap->cellFilterCollection()->setCase( eclipseCase ); } caf::SelectionManager::instance()->setSelectedItem( eclipseContourMap ); @@ -145,6 +147,7 @@ void RicNewContourMapViewFeature::onActionTriggered( bool isChecked ) if ( geoMechCase ) { geoMechCase->updateConnectedEditors(); + eclipseContourMap->cellFilterCollection()->setCase( geoMechCase ); caf::SelectionManager::instance()->setSelectedItem( geoMechContourMap ); geoMechContourMap->createDisplayModelAndRedraw(); geoMechContourMap->zoomAll(); diff --git a/ApplicationLibCode/ModelVisualization/CMakeLists_files.cmake b/ApplicationLibCode/ModelVisualization/CMakeLists_files.cmake index f4f9769204..17d1b814a1 100644 --- a/ApplicationLibCode/ModelVisualization/CMakeLists_files.cmake +++ b/ApplicationLibCode/ModelVisualization/CMakeLists_files.cmake @@ -49,7 +49,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RivContourMapProjectionPartMgr.h ${CMAKE_CURRENT_LIST_DIR}/RivAnnotationsPartMgr.h ${CMAKE_CURRENT_LIST_DIR}/RivTextAnnotationPartMgr.h ${CMAKE_CURRENT_LIST_DIR}/RivReachCircleAnnotationPartMgr.h -${CMAKE_CURRENT_LIST_DIR}/RivPolylineAnnotationPartMgr.h ${CMAKE_CURRENT_LIST_DIR}/RivReachCircleAnnotationSourceInfo.h ${CMAKE_CURRENT_LIST_DIR}/RivPolylinesAnnotationSourceInfo.h ${CMAKE_CURRENT_LIST_DIR}/RivPolylineGenerator.h @@ -58,6 +57,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RivTextLabelSourceInfo.h ${CMAKE_CURRENT_LIST_DIR}/RivDiskGeometryGenerator.h ${CMAKE_CURRENT_LIST_DIR}/RivWellDiskPartMgr.h ${CMAKE_CURRENT_LIST_DIR}/RivElementVectorResultPartMgr.h +${CMAKE_CURRENT_LIST_DIR}/RivPolylinePartMgr.h +${CMAKE_CURRENT_LIST_DIR}/RivCellFilterPartMgr.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -105,7 +106,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RivContourMapProjectionPartMgr.cpp ${CMAKE_CURRENT_LIST_DIR}/RivAnnotationsPartMgr.cpp ${CMAKE_CURRENT_LIST_DIR}/RivTextAnnotationPartMgr.cpp ${CMAKE_CURRENT_LIST_DIR}/RivReachCircleAnnotationPartMgr.cpp -${CMAKE_CURRENT_LIST_DIR}/RivPolylineAnnotationPartMgr.cpp ${CMAKE_CURRENT_LIST_DIR}/RivReachCircleAnnotationSourceInfo.cpp ${CMAKE_CURRENT_LIST_DIR}/RivPolylinesAnnotationSourceInfo.cpp ${CMAKE_CURRENT_LIST_DIR}/RivPolylineGenerator.cpp @@ -114,6 +114,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RivTextLabelSourceInfo.cpp ${CMAKE_CURRENT_LIST_DIR}/RivDiskGeometryGenerator.cpp ${CMAKE_CURRENT_LIST_DIR}/RivWellDiskPartMgr.cpp ${CMAKE_CURRENT_LIST_DIR}/RivElementVectorResultPartMgr.cpp +${CMAKE_CURRENT_LIST_DIR}/RivPolylinePartMgr.cpp +${CMAKE_CURRENT_LIST_DIR}/RivCellFilterPartMgr.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationLibCode/ModelVisualization/RivAnnotationsPartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivAnnotationsPartMgr.cpp index 09bc85c449..126d379e78 100644 --- a/ApplicationLibCode/ModelVisualization/RivAnnotationsPartMgr.cpp +++ b/ApplicationLibCode/ModelVisualization/RivAnnotationsPartMgr.cpp @@ -27,10 +27,12 @@ #include "RimPolylinesFromFileAnnotationInView.h" #include "RimUserDefinedPolylinesAnnotationInView.h" -#include "RivPolylineAnnotationPartMgr.h" +#include "RivPolylinePartMgr.h" #include "RivReachCircleAnnotationPartMgr.h" #include "RivTextAnnotationPartMgr.h" +#include "cafPdmObject.h" + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -113,12 +115,12 @@ void RivAnnotationsPartMgr::createAnnotationPartManagers() { for ( auto annotation : userDefinedPolylineAnnotations ) { - auto* apm = new RivPolylineAnnotationPartMgr( m_rimView, annotation ); + auto* apm = new RivPolylinePartMgr( m_rimView, annotation, coll ); m_polylineAnnotationPartMgrs.push_back( apm ); } for ( auto annotation : polylineFromFileAnnotations ) { - auto* apm = new RivPolylineAnnotationPartMgr( m_rimView, annotation ); + auto* apm = new RivPolylinePartMgr( m_rimView, annotation, coll ); m_polylineAnnotationPartMgrs.push_back( apm ); } } diff --git a/ApplicationLibCode/ModelVisualization/RivAnnotationsPartMgr.h b/ApplicationLibCode/ModelVisualization/RivAnnotationsPartMgr.h index 4fe9f1dc85..967ea0132b 100644 --- a/ApplicationLibCode/ModelVisualization/RivAnnotationsPartMgr.h +++ b/ApplicationLibCode/ModelVisualization/RivAnnotationsPartMgr.h @@ -37,12 +37,9 @@ class DisplayCoordTransform; } class Rim3dView; -class RimAnnotationInViewCollection; class RivTextAnnotationPartMgr; class RivReachCircleAnnotationPartMgr; -class RivPolylineAnnotationPartMgr; -class RimSimWellInView; -class RimSimWellInViewCollection; +class RivPolylinePartMgr; class RivAnnotationsPartMgr : public cvf::Object { @@ -63,5 +60,5 @@ private: caf::PdmPointer m_rimView; cvf::Collection m_textAnnotationPartMgrs; cvf::Collection m_reachCircleAnnotationPartMgrs; - cvf::Collection m_polylineAnnotationPartMgrs; + cvf::Collection m_polylineAnnotationPartMgrs; }; diff --git a/ApplicationLibCode/ModelVisualization/RivCellFilterPartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivCellFilterPartMgr.cpp new file mode 100644 index 0000000000..49a9fe3d79 --- /dev/null +++ b/ApplicationLibCode/ModelVisualization/RivCellFilterPartMgr.cpp @@ -0,0 +1,89 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021 Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RivCellFilterPartMgr.h" + +#include "Rim3dView.h" +#include "RimCellFilterCollection.h" +#include "RimPolygonFilter.h" + +#include "RivPolylinePartMgr.h" + +#include "cafPdmObject.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivCellFilterPartMgr::RivCellFilterPartMgr( Rim3dView* view ) + : m_rimView( view ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivCellFilterPartMgr::~RivCellFilterPartMgr() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivCellFilterPartMgr::appendGeometryPartsToModel( cvf::ModelBasicList* model, + const caf::DisplayCoordTransform* displayCoordTransform, + const cvf::BoundingBox& boundingBox ) +{ + createCellFilterPartManagers(); + + for ( auto& partMgr : m_cellFilterPartMgrs ) + { + partMgr->appendDynamicGeometryPartsToModel( model, displayCoordTransform, boundingBox ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivCellFilterPartMgr::createCellFilterPartManagers() +{ + std::vector colls; + m_rimView->descendantsIncludingThisOfType( colls ); + + if ( colls.empty() ) return; + auto coll = colls.front(); + + clearGeometryCache(); + + for ( auto filter : coll->filters() ) + { + RimPolygonFilter* polyFilter = dynamic_cast( filter ); + if ( polyFilter ) + { + RivPolylinePartMgr* ppm = new RivPolylinePartMgr( m_rimView, polyFilter, coll ); + m_cellFilterPartMgrs.push_back( ppm ); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivCellFilterPartMgr::clearGeometryCache() +{ + m_cellFilterPartMgrs.clear(); +} diff --git a/ApplicationLibCode/ModelVisualization/RivCellFilterPartMgr.h b/ApplicationLibCode/ModelVisualization/RivCellFilterPartMgr.h new file mode 100644 index 0000000000..a58d0d1916 --- /dev/null +++ b/ApplicationLibCode/ModelVisualization/RivCellFilterPartMgr.h @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021 Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmPointer.h" +#include "cvfAssert.h" +#include "cvfCollection.h" +#include "cvfObject.h" + +namespace cvf +{ +class BoundingBox; +class Part; +class ModelBasicList; +class Transform; +class Font; +} // namespace cvf +namespace caf +{ +class DisplayCoordTransform; +} + +class Rim3dView; +class RivPolylinePartMgr; + +class RivCellFilterPartMgr : public cvf::Object +{ +public: + RivCellFilterPartMgr( Rim3dView* view ); + ~RivCellFilterPartMgr() override; + + void appendGeometryPartsToModel( cvf::ModelBasicList* model, + const caf::DisplayCoordTransform* displayCoordTransform, + const cvf::BoundingBox& boundingBox ); + + void clearGeometryCache(); + +private: + void createCellFilterPartManagers(); + +private: + caf::PdmPointer m_rimView; + cvf::Collection m_cellFilterPartMgrs; +}; diff --git a/ApplicationLibCode/ModelVisualization/RivMeasurementPartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivMeasurementPartMgr.cpp index 2eab5a392f..fac460ef3e 100644 --- a/ApplicationLibCode/ModelVisualization/RivMeasurementPartMgr.cpp +++ b/ApplicationLibCode/ModelVisualization/RivMeasurementPartMgr.cpp @@ -26,19 +26,13 @@ #include "RiaPreferences.h" #include "Rim3dView.h" -#include "RimAnnotationInViewCollection.h" #include "RimMeasurement.h" -#include "RimPolylinesFromFileAnnotationInView.h" #include "RimProject.h" -#include "RimUserDefinedPolylinesAnnotationInView.h" #include "RiuGuiTheme.h" #include "RivPartPriority.h" -#include "RivPolylineAnnotationPartMgr.h" #include "RivPolylineGenerator.h" -#include "RivReachCircleAnnotationPartMgr.h" -#include "RivTextAnnotationPartMgr.h" #include "cafDisplayCoordTransform.h" #include "cafEffectGenerator.h" diff --git a/ApplicationLibCode/ModelVisualization/RivPolylineAnnotationPartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivPolylineAnnotationPartMgr.cpp deleted file mode 100644 index 6b144a41f4..0000000000 --- a/ApplicationLibCode/ModelVisualization/RivPolylineAnnotationPartMgr.cpp +++ /dev/null @@ -1,285 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2018- Equinor ASA -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "RivPolylineAnnotationPartMgr.h" - -#include "RiaBoundingBoxTools.h" -#include "RiaGuiApplication.h" - -#include "Rim3dView.h" -#include "RimAnnotationCollection.h" -#include "RimAnnotationInViewCollection.h" -#include "RimAnnotationLineAppearance.h" -#include "RimEclipseView.h" -#include "RimPolylinesAnnotation.h" -#include "RimPolylinesAnnotationInView.h" - -#include "RigMainGrid.h" -#include "RigPolyLinesData.h" - -#include "RivPartPriority.h" -#include "RivPolylineGenerator.h" -#include "RivPolylinesAnnotationSourceInfo.h" - -#include "cafEffectGenerator.h" - -#include "cafDisplayCoordTransform.h" -#include "cvfDrawableGeo.h" -#include "cvfDrawableText.h" -#include "cvfDrawableVectors.h" -#include "cvfGeometryBuilderTriangles.h" -#include "cvfGeometryUtils.h" -#include "cvfModelBasicList.h" -#include "cvfPart.h" -#include "cvfTransform.h" - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RivPolylineAnnotationPartMgr::RivPolylineAnnotationPartMgr( Rim3dView* view, RimPolylinesAnnotationInView* annotationInView ) - : m_rimView( view ) - , m_rimAnnotationInView( annotationInView ) -{ -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RivPolylineAnnotationPartMgr::~RivPolylineAnnotationPartMgr() -{ -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivPolylineAnnotationPartMgr::buildPolylineAnnotationParts( const caf::DisplayCoordTransform* displayXf ) -{ - clearAllGeometry(); - - auto rimAnnotation = m_rimAnnotationInView->sourceAnnotation(); - if ( !rimAnnotation->isEmpty() && rimAnnotation->isActive() ) - { - auto lineColor = rimAnnotation->appearance()->color(); - auto isDashedLine = rimAnnotation->appearance()->isDashed(); - auto lineThickness = rimAnnotation->appearance()->thickness(); - - auto* collection = annotationCollection(); - if ( !collection ) return; - - auto linesInDomain = getPolylinesPointsInDomain( collection->snapAnnotations(), collection->annotationPlaneZ() ); - auto linesInDisplay = transformPolylinesPointsToDisplay( linesInDomain, displayXf ); - - // Line part - if ( rimAnnotation->showLines() ) - { - cvf::ref drawableGeo = - RivPolylineGenerator::createLineAlongPolylineDrawable( linesInDisplay, rimAnnotation->closePolyline() ); - cvf::ref part = new cvf::Part; - part->setName( "RivPolylineAnnotationPartMgr" ); - part->setDrawable( drawableGeo.p() ); - - caf::MeshEffectGenerator effgen( lineColor ); - effgen.setLineWidth( lineThickness ); - if ( isDashedLine ) effgen.setLineStipple( true ); - cvf::ref eff = effgen.generateCachedEffect(); - - part->setEffect( eff.p() ); - part->setPriority( RivPartPriority::PartType::MeshLines ); - - cvf::ref sourceInfo = new RivPolylinesAnnotationSourceInfo( rimAnnotation ); - part->setSourceInfo( sourceInfo.p() ); - - m_linePart = part; - } - - // Sphere part - if ( rimAnnotation->showSpheres() ) - { - auto sphereColor = rimAnnotation->appearance()->sphereColor(); - double sphereRadiusFactor = rimAnnotation->appearance()->sphereRadiusFactor(); - - cvf::ref vertices = new cvf::Vec3fArray; - cvf::ref vecRes = new cvf::Vec3fArray; - cvf::ref colors = new cvf::Color3fArray; - - size_t pointCount = 0; - for ( const auto& line : linesInDisplay ) - pointCount += line.size(); - vertices->reserve( pointCount ); - vecRes->reserve( pointCount ); - colors->reserve( pointCount ); - - for ( const auto& line : linesInDisplay ) - { - for ( const auto& v : line ) - { - vertices->add( cvf::Vec3f( v ) ); - vecRes->add( cvf::Vec3f::X_AXIS ); - colors->add( sphereColor ); - } - } - - cvf::ref vectorDrawable; - if ( RiaGuiApplication::instance()->useShaders() ) - { - // NOTE: Drawable vectors must be rendered using shaders when the rest of the application is rendered - // using shaders Drawing vectors using fixed function when rest of the application uses shaders causes - // visual artifacts - vectorDrawable = new cvf::DrawableVectors( "u_transformationMatrix", "u_color" ); - } - else - { - vectorDrawable = new cvf::DrawableVectors(); - } - - vectorDrawable->setVectors( vertices.p(), vecRes.p() ); - vectorDrawable->setColors( colors.p() ); - - cvf::GeometryBuilderTriangles builder; - double cellRadius = 15.0; - auto eclipseView = dynamic_cast( m_rimView.p() ); - if ( eclipseView ) - { - double characteristicCellSize = eclipseView->mainGrid()->characteristicIJCellSize(); - cellRadius = sphereRadiusFactor * characteristicCellSize; - } - - cvf::GeometryUtils::createSphere( cellRadius, 15, 15, &builder ); - vectorDrawable->setGlyph( builder.trianglesUShort().p(), builder.vertices().p() ); - - cvf::ref part = new cvf::Part; - part->setName( "RivPolylineAnnotationPartMgr" ); - part->setDrawable( vectorDrawable.p() ); - - part->setEffect( new cvf::Effect() ); - part->setPriority( RivPartPriority::PartType::MeshLines ); - - cvf::ref sourceInfo = new RivPolylinesAnnotationSourceInfo( rimAnnotation ); - part->setSourceInfo( sourceInfo.p() ); - - m_spherePart = part; - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector> - RivPolylineAnnotationPartMgr::getPolylinesPointsInDomain( bool snapToPlaneZ, double planeZ ) -{ - auto polylines = m_rimAnnotationInView->sourceAnnotation()->polyLinesData()->polyLines(); - if ( !snapToPlaneZ ) return polylines; - - std::vector> polylinesInDisplay; - for ( const auto& pts : polylines ) - { - std::vector polyline; - for ( const auto& pt : pts ) - { - auto ptInDisp = pt; - ptInDisp.z() = planeZ; - polyline.push_back( ptInDisp ); - } - polylinesInDisplay.push_back( polyline ); - } - return polylinesInDisplay; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector> - RivPolylineAnnotationPartMgr::transformPolylinesPointsToDisplay( const std::vector>& pointsInDomain, - const caf::DisplayCoordTransform* displayXf ) -{ - std::vector> pointsInDisplay; - for ( const auto& pts : pointsInDomain ) - { - std::vector displayCoords = displayXf->transformToDisplayCoords( pts ); - - pointsInDisplay.push_back( displayCoords ); - } - return pointsInDisplay; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RivPolylineAnnotationPartMgr::isPolylinesInBoundingBox( const cvf::BoundingBox& boundingBox ) -{ - auto coll = annotationCollection(); - if ( !coll ) return false; - - auto effectiveBoundingBox = RiaBoundingBoxTools::inflate( boundingBox, 3 ); - for ( const auto& pts : getPolylinesPointsInDomain( coll->snapAnnotations(), coll->annotationPlaneZ() ) ) - { - for ( const auto& pt : pts ) - { - if ( effectiveBoundingBox.contains( pt ) ) return true; - } - } - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivPolylineAnnotationPartMgr::clearAllGeometry() -{ - m_linePart = nullptr; - m_spherePart = nullptr; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimAnnotationInViewCollection* RivPolylineAnnotationPartMgr::annotationCollection() const -{ - std::vector colls; - m_rimView->descendantsIncludingThisOfType( colls ); - return !colls.empty() ? colls.front() : nullptr; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivPolylineAnnotationPartMgr::appendDynamicGeometryPartsToModel( cvf::ModelBasicList* model, - const caf::DisplayCoordTransform* displayXf, - const cvf::BoundingBox& boundingBox ) -{ - auto rimAnnotation = m_rimAnnotationInView->sourceAnnotation(); - if ( !rimAnnotation ) return; - if ( rimAnnotation->isEmpty() ) return; - if ( !m_rimAnnotationInView->isVisible() ) return; - - // Check bounding box - if ( !isPolylinesInBoundingBox( boundingBox ) ) return; - - buildPolylineAnnotationParts( displayXf ); - - if ( m_linePart.notNull() ) - { - model->addPart( m_linePart.p() ); - } - - if ( m_spherePart.notNull() ) - { - model->addPart( m_spherePart.p() ); - } -} diff --git a/ApplicationLibCode/ModelVisualization/RivPolylinePartMgr.cpp b/ApplicationLibCode/ModelVisualization/RivPolylinePartMgr.cpp new file mode 100644 index 0000000000..32bde9d097 --- /dev/null +++ b/ApplicationLibCode/ModelVisualization/RivPolylinePartMgr.cpp @@ -0,0 +1,274 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RivPolylinePartMgr.h" + +#include "RiaBoundingBoxTools.h" +#include "RiaGuiApplication.h" + +#include "Rim3dView.h" +#include "RimEclipseView.h" +#include "RimPolylinesDataInterface.h" + +#include "RigMainGrid.h" +#include "RigPolyLinesData.h" + +#include "RivPartPriority.h" +#include "RivPolylineGenerator.h" + +#include "cafEffectGenerator.h" + +#include "cafDisplayCoordTransform.h" +#include "cvfDrawableGeo.h" +#include "cvfDrawableText.h" +#include "cvfDrawableVectors.h" +#include "cvfGeometryBuilderTriangles.h" +#include "cvfGeometryUtils.h" +#include "cvfModelBasicList.h" +#include "cvfPart.h" +#include "cvfTransform.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivPolylinePartMgr::RivPolylinePartMgr( Rim3dView* view, + RimPolylinesDataInterface* polylineInterface, + caf::PdmObject* collection ) + : m_rimView( view ) + , m_polylineInterface( polylineInterface ) + , m_viewCollection( collection ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivPolylinePartMgr::~RivPolylinePartMgr() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RivPolylinePartMgr::isPolylinesInBoundingBox( std::vector> polyline, + const cvf::BoundingBox& boundingBox ) +{ + auto effectiveBoundingBox = RiaBoundingBoxTools::inflate( boundingBox, 3 ); + for ( const auto& pts : polyline ) + { + for ( const auto& pt : pts ) + { + if ( effectiveBoundingBox.contains( pt ) ) return true; + } + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivPolylinePartMgr::buildPolylineParts( const caf::DisplayCoordTransform* displayXf, + const cvf::BoundingBox& boundingBox ) +{ + auto polylineDef = m_polylineInterface->polyLinesData(); + if ( polylineDef.isNull() || polylineDef->polyLines().size() == 0 ) + { + clearAllGeometry(); + return; + } + + auto linesInDomain = getPolylinesPointsInDomain( polylineDef->lockToZPlane(), polylineDef->lockedZValue() ); + + if ( !isPolylinesInBoundingBox( linesInDomain, boundingBox ) ) return; + + auto linesInDisplay = transformPolylinesPointsToDisplay( linesInDomain, displayXf ); + + clearAllGeometry(); + + // Line part + if ( polylineDef->showLines() ) + { + cvf::ref drawableGeo = + RivPolylineGenerator::createLineAlongPolylineDrawable( linesInDisplay, polylineDef->closePolyline() ); + cvf::ref part = new cvf::Part; + part->setName( "RivPolylinePartMgr" ); + part->setDrawable( drawableGeo.p() ); + + caf::MeshEffectGenerator effgen( polylineDef->lineColor() ); + effgen.setLineWidth( polylineDef->lineThickness() ); + // if ( isDashedLine ) effgen.setLineStipple( true ); + cvf::ref eff = effgen.generateCachedEffect(); + + part->setEffect( eff.p() ); + part->setPriority( RivPartPriority::PartType::MeshLines ); + + m_linePart = part; + } + + // Sphere part + if ( polylineDef->showSpheres() ) + { + auto sphereColor = polylineDef->sphereColor(); + double sphereRadiusFactor = polylineDef->sphereRadiusFactor(); + + cvf::ref vertices = new cvf::Vec3fArray; + cvf::ref vecRes = new cvf::Vec3fArray; + cvf::ref colors = new cvf::Color3fArray; + + size_t pointCount = 0; + for ( const auto& line : linesInDisplay ) + pointCount += line.size(); + vertices->reserve( pointCount ); + vecRes->reserve( pointCount ); + colors->reserve( pointCount ); + + for ( const auto& line : linesInDisplay ) + { + for ( const auto& v : line ) + { + vertices->add( cvf::Vec3f( v ) ); + vecRes->add( cvf::Vec3f::X_AXIS ); + colors->add( sphereColor ); + } + } + + cvf::ref vectorDrawable; + if ( RiaGuiApplication::instance()->useShaders() ) + { + // NOTE: Drawable vectors must be rendered using shaders when the rest of the application is rendered + // using shaders Drawing vectors using fixed function when rest of the application uses shaders causes + // visual artifacts + vectorDrawable = new cvf::DrawableVectors( "u_transformationMatrix", "u_color" ); + } + else + { + vectorDrawable = new cvf::DrawableVectors(); + } + + vectorDrawable->setVectors( vertices.p(), vecRes.p() ); + vectorDrawable->setColors( colors.p() ); + + double cellRadius = 15.0; + auto eclipseView = dynamic_cast( m_rimView.p() ); + if ( eclipseView ) + { + double characteristicCellSize = eclipseView->mainGrid()->characteristicIJCellSize(); + cellRadius = sphereRadiusFactor * characteristicCellSize; + } + + cvf::GeometryBuilderTriangles builder; + cvf::GeometryUtils::createSphere( cellRadius, 15, 15, &builder ); + vectorDrawable->setGlyph( builder.trianglesUShort().p(), builder.vertices().p() ); + + cvf::ref part = new cvf::Part; + part->setName( "RivPolylinePartMgr" ); + part->setDrawable( vectorDrawable.p() ); + + part->setEffect( new cvf::Effect() ); + part->setPriority( RivPartPriority::PartType::MeshLines ); + + m_spherePart = part; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector> RivPolylinePartMgr::getPolylinesPointsInDomain( bool snapToPlaneZ, double planeZ ) +{ + auto polylines = m_polylineInterface->polyLinesData()->polyLines(); + if ( !snapToPlaneZ ) return polylines; + + std::vector> polylinesInDisplay; + for ( const auto& pts : polylines ) + { + std::vector polyline; + for ( const auto& pt : pts ) + { + auto ptInDisp = pt; + ptInDisp.z() = planeZ; + polyline.push_back( ptInDisp ); + } + polylinesInDisplay.push_back( polyline ); + } + return polylinesInDisplay; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector> + RivPolylinePartMgr::transformPolylinesPointsToDisplay( const std::vector>& pointsInDomain, + const caf::DisplayCoordTransform* displayXf ) +{ + std::vector> pointsInDisplay; + for ( const auto& pts : pointsInDomain ) + { + std::vector displayCoords = displayXf->transformToDisplayCoords( pts ); + + pointsInDisplay.push_back( displayCoords ); + } + return pointsInDisplay; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivPolylinePartMgr::clearAllGeometry() +{ + m_linePart = nullptr; + m_spherePart = nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RivPolylinePartMgr::collectionVisible() +{ + if ( m_viewCollection && m_viewCollection->objectToggleField() ) + { + caf::PdmField* field = dynamic_cast*>( m_viewCollection->objectToggleField() ); + return field->value(); + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivPolylinePartMgr::appendDynamicGeometryPartsToModel( cvf::ModelBasicList* model, + const caf::DisplayCoordTransform* displayXf, + const cvf::BoundingBox& boundingBox ) +{ + if ( !collectionVisible() ) return; + + // build the lines + buildPolylineParts( displayXf, boundingBox ); + + // add the things we should + if ( m_linePart.notNull() ) + { + model->addPart( m_linePart.p() ); + } + + if ( m_spherePart.notNull() ) + { + model->addPart( m_spherePart.p() ); + } +} diff --git a/ApplicationLibCode/ModelVisualization/RivPolylineAnnotationPartMgr.h b/ApplicationLibCode/ModelVisualization/RivPolylinePartMgr.h similarity index 53% rename from ApplicationLibCode/ModelVisualization/RivPolylineAnnotationPartMgr.h rename to ApplicationLibCode/ModelVisualization/RivPolylinePartMgr.h index 9cd8c71ecc..73eaec489e 100644 --- a/ApplicationLibCode/ModelVisualization/RivPolylineAnnotationPartMgr.h +++ b/ApplicationLibCode/ModelVisualization/RivPolylinePartMgr.h @@ -22,6 +22,7 @@ #include "cvfObject.h" #include "cvfVector3.h" +#include "cafPdmObject.h" #include "cafPdmPointer.h" #include @@ -34,41 +35,41 @@ class ModelBasicList; class Transform; class Font; } // namespace cvf + namespace caf { class DisplayCoordTransform; } class Rim3dView; -class RimPolylinesAnnotationInView; -class RimAnnotationInViewCollection; +class RimPolylinesDataInterface; -class RivPolylineAnnotationPartMgr : public cvf::Object +class RivPolylinePartMgr : public cvf::Object { - using Vec3d = cvf::Vec3d; - public: - RivPolylineAnnotationPartMgr( Rim3dView* view, RimPolylinesAnnotationInView* annotation ); - ~RivPolylineAnnotationPartMgr() override; + RivPolylinePartMgr( Rim3dView* view, RimPolylinesDataInterface* polylines, caf::PdmObject* collection ); + ~RivPolylinePartMgr() override; void appendDynamicGeometryPartsToModel( cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayXf, const cvf::BoundingBox& boundingBox ); private: - void buildPolylineAnnotationParts( const caf::DisplayCoordTransform* displayXf ); + bool isPolylinesInBoundingBox( std::vector> polyline, const cvf::BoundingBox& boundingBox ); + void buildPolylineParts( const caf::DisplayCoordTransform* displayXf, const cvf::BoundingBox& boundingBox ); - std::vector> getPolylinesPointsInDomain( bool snapToPlaneZ, double planeZ ); - std::vector> transformPolylinesPointsToDisplay( const std::vector>& pointsInDomain, - const caf::DisplayCoordTransform* displayXf ); + std::vector> getPolylinesPointsInDomain( bool snapToPlaneZ, double planeZ ); + std::vector> + transformPolylinesPointsToDisplay( const std::vector>& pointsInDomain, + const caf::DisplayCoordTransform* displayXf ); - bool isPolylinesInBoundingBox( const cvf::BoundingBox& boundingBox ); + bool collectionVisible(); - void clearAllGeometry(); - RimAnnotationInViewCollection* annotationCollection() const; + void clearAllGeometry(); - caf::PdmPointer m_rimView; - caf::PdmPointer m_rimAnnotationInView; - cvf::ref m_linePart; - cvf::ref m_spherePart; + RimPolylinesDataInterface* m_polylineInterface; + caf::PdmObject* m_viewCollection; + caf::PdmPointer m_rimView; + cvf::ref m_linePart; + cvf::ref m_spherePart; }; diff --git a/ApplicationLibCode/ProjectDataModel/Annotations/RimPolylinesAnnotationInView.cpp b/ApplicationLibCode/ProjectDataModel/Annotations/RimPolylinesAnnotationInView.cpp index 6fdcf302e9..a2dda86312 100644 --- a/ApplicationLibCode/ProjectDataModel/Annotations/RimPolylinesAnnotationInView.cpp +++ b/ApplicationLibCode/ProjectDataModel/Annotations/RimPolylinesAnnotationInView.cpp @@ -19,8 +19,11 @@ #include "RimPolylinesAnnotationInView.h" #include "RimAnnotationCollectionBase.h" #include "RimAnnotationGroupCollection.h" +#include "RimAnnotationInViewCollection.h" #include "RimPolylinesAnnotation.h" +#include "RigPolyLinesData.h" + CAF_PDM_SOURCE_INIT( RimPolylinesAnnotationInView, "RimPolylinesAnnotationInView" ); //-------------------------------------------------------------------------------------------------- @@ -122,3 +125,21 @@ caf::PdmFieldHandle* RimPolylinesAnnotationInView::userDescriptionField() { return m_sourceAnnotation ? m_sourceAnnotation->userDescriptionField() : nullptr; } + +cvf::ref RimPolylinesAnnotationInView::polyLinesData() const +{ + auto retval = m_sourceAnnotation->polyLinesData(); + if ( !isVisible() ) + { + retval->setVisibility( false, false ); + } + + RimAnnotationInViewCollection* coll; + firstAncestorOrThisOfType( coll ); + if ( coll ) + { + retval->setZPlaneLock( coll->snapAnnotations(), coll->annotationPlaneZ() ); + } + + return retval; +} diff --git a/ApplicationLibCode/ProjectDataModel/Annotations/RimPolylinesAnnotationInView.h b/ApplicationLibCode/ProjectDataModel/Annotations/RimPolylinesAnnotationInView.h index 6f35e48425..a5278d122a 100644 --- a/ApplicationLibCode/ProjectDataModel/Annotations/RimPolylinesAnnotationInView.h +++ b/ApplicationLibCode/ProjectDataModel/Annotations/RimPolylinesAnnotationInView.h @@ -20,6 +20,8 @@ #include "RimAnnotationLineAppearance.h" +#include "RimPolylinesDataInterface.h" + #include "cafAppEnum.h" #include "cafPdmChildArrayField.h" #include "cafPdmField.h" @@ -46,7 +48,7 @@ class RimPolylinesAnnotation; /// /// //================================================================================================== -class RimPolylinesAnnotationInView : public caf::PdmObject +class RimPolylinesAnnotationInView : public caf::PdmObject, public RimPolylinesDataInterface { CAF_PDM_HEADER_INIT; @@ -60,6 +62,8 @@ public: bool isVisible() const; + cvf::ref polyLinesData() const override; + protected: void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; caf::PdmFieldHandle* objectToggleField() override; diff --git a/ApplicationLibCode/ProjectDataModel/Annotations/RimPolylinesFromFileAnnotation.cpp b/ApplicationLibCode/ProjectDataModel/Annotations/RimPolylinesFromFileAnnotation.cpp index d2e42584ac..9c35c70fa7 100644 --- a/ApplicationLibCode/ProjectDataModel/Annotations/RimPolylinesFromFileAnnotation.cpp +++ b/ApplicationLibCode/ProjectDataModel/Annotations/RimPolylinesFromFileAnnotation.cpp @@ -143,6 +143,11 @@ void RimPolylinesFromFileAnnotation::readPolyLinesFile( QString* errorMessage ) //-------------------------------------------------------------------------------------------------- cvf::ref RimPolylinesFromFileAnnotation::polyLinesData() { + auto ap = appearance(); + m_polyLinesData->setVisibility( m_showLines(), m_showSpheres() ); + m_polyLinesData->setSphereAppearance( ap->sphereRadiusFactor(), ap->sphereColor() ); + m_polyLinesData->setLineAppearance( ap->thickness(), ap->color(), m_closePolyline ); + return m_polyLinesData; } diff --git a/ApplicationLibCode/ProjectDataModel/Annotations/RimUserDefinedPolylinesAnnotation.cpp b/ApplicationLibCode/ProjectDataModel/Annotations/RimUserDefinedPolylinesAnnotation.cpp index b62a8e681d..4b32332d56 100644 --- a/ApplicationLibCode/ProjectDataModel/Annotations/RimUserDefinedPolylinesAnnotation.cpp +++ b/ApplicationLibCode/ProjectDataModel/Annotations/RimUserDefinedPolylinesAnnotation.cpp @@ -80,7 +80,12 @@ cvf::ref RimUserDefinedPolylinesAnnotation::polyLinesData() { line.push_back( target->targetPointXYZ() ); } - pld->setPolyLines( { line } ); + pld->setPolyLine( line ); + + auto ap = appearance(); + pld->setVisibility( m_showLines(), m_showSpheres() ); + pld->setSphereAppearance( ap->sphereRadiusFactor(), ap->sphereColor() ); + pld->setLineAppearance( ap->thickness(), ap->color(), m_closePolyline ); return pld; } diff --git a/ApplicationLibCode/ProjectDataModel/CMakeLists_files.cmake b/ApplicationLibCode/ProjectDataModel/CMakeLists_files.cmake index e54a422290..96c60b9ae5 100644 --- a/ApplicationLibCode/ProjectDataModel/CMakeLists_files.cmake +++ b/ApplicationLibCode/ProjectDataModel/CMakeLists_files.cmake @@ -166,6 +166,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimCustomObjectiveFunction.h ${CMAKE_CURRENT_LIST_DIR}/RimCustomObjectiveFunctionWeight.h ${CMAKE_CURRENT_LIST_DIR}/RimEquilibriumAxisAnnotation.h ${CMAKE_CURRENT_LIST_DIR}/RimTimeAxisAnnotation.h +${CMAKE_CURRENT_LIST_DIR}/RimPolylinesDataInterface.h ) diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/CMakeLists_files.cmake b/ApplicationLibCode/ProjectDataModel/CellFilters/CMakeLists_files.cmake index eaa6f5e9d1..981011eb8c 100644 --- a/ApplicationLibCode/ProjectDataModel/CellFilters/CMakeLists_files.cmake +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/CMakeLists_files.cmake @@ -11,6 +11,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechPropertyFilter.h ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechPropertyFilterCollection.h ${CMAKE_CURRENT_LIST_DIR}/RimPolygonFilter.h ${CMAKE_CURRENT_LIST_DIR}/RimUserDefinedFilter.h +${CMAKE_CURRENT_LIST_DIR}/RimCellFilterIntervalTool.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -25,6 +26,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechPropertyFilter.cpp ${CMAKE_CURRENT_LIST_DIR}/RimGeoMechPropertyFilterCollection.cpp ${CMAKE_CURRENT_LIST_DIR}/RimPolygonFilter.cpp ${CMAKE_CURRENT_LIST_DIR}/RimUserDefinedFilter.cpp +${CMAKE_CURRENT_LIST_DIR}/RimCellFilterIntervalTool.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilter.cpp b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilter.cpp index 0644a84f55..ea330c5e6b 100644 --- a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilter.cpp +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilter.cpp @@ -112,13 +112,24 @@ void RimCellFilter::setActive( bool active ) } //-------------------------------------------------------------------------------------------------- -/// +/// Is the filter turned on in the explorer tree? //-------------------------------------------------------------------------------------------------- bool RimCellFilter::isActive() const { return m_isActive(); } +//-------------------------------------------------------------------------------------------------- +/// Is the cell filter doing active filtering, or is it just showning outline, etc. in the view +/// - isActive == true -> filter enabled in explorer +/// - isFilterEnabled == true -> filter enabled in explorer and is actually filtering cells, too +/// Default implementation just returns the isActive state. +//-------------------------------------------------------------------------------------------------- +bool RimCellFilter::isFilterEnabled() const +{ + return m_isActive(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilter.h b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilter.h index aa41b56d5f..e90026aa61 100644 --- a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilter.h +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilter.h @@ -56,6 +56,8 @@ public: bool isActive() const; void setActive( bool active ); + virtual bool isFilterEnabled() const; + caf::AppEnum filterMode() const; QString modeString() const; diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.cpp b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.cpp index b86f5d1a60..6dcf3068e9 100644 --- a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.cpp @@ -18,12 +18,10 @@ #include "RimCellFilterCollection.h" -#include "RigPolyLinesData.h" #include "Rim3dView.h" #include "RimCase.h" #include "RimCellFilter.h" #include "RimCellRangeFilter.h" -#include "RimGeoMechView.h" #include "RimPolygonFilter.h" #include "RimUserDefinedFilter.h" #include "RimViewController.h" @@ -88,6 +86,18 @@ void RimCellFilterCollection::setActive( bool bActive ) updateIconState(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCellFilterCollection::setCase( RimCase* theCase ) +{ + for ( RimCellFilter* filter : m_cellFilters ) + { + RimPolygonFilter* polyFilter = dynamic_cast( filter ); + if ( polyFilter ) polyFilter->setCase( theCase ); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -205,7 +215,7 @@ bool RimCellFilterCollection::hasActiveFilters() const for ( const auto& filter : m_cellFilters ) { - if ( filter->isActive() ) return true; + if ( filter->isFilterEnabled() ) return true; } return false; @@ -220,7 +230,7 @@ bool RimCellFilterCollection::hasActiveIncludeFilters() const for ( const auto& filter : m_cellFilters ) { - if ( filter->isActive() && filter->filterMode() == RimCellFilter::INCLUDE ) return true; + if ( filter->isFilterEnabled() && filter->filterMode() == RimCellFilter::INCLUDE ) return true; } return false; @@ -233,8 +243,8 @@ RimPolygonFilter* RimCellFilterCollection::addNewPolygonFilter( RimCase* srcCase { RimPolygonFilter* pFilter = new RimPolygonFilter(); pFilter->setCase( srcCase ); - pFilter->setActive( false ); addFilter( pFilter ); + pFilter->enablePicking( true ); onFilterUpdated( pFilter ); return pFilter; } @@ -361,7 +371,7 @@ void RimCellFilterCollection::compoundCellRangeFilter( cvf::CellRangeFilter* cel for ( RimCellFilter* filter : m_cellFilters ) { - if ( filter->isActive() && static_cast( filter->gridIndex() ) == gridIndex ) + if ( filter->isFilterEnabled() && static_cast( filter->gridIndex() ) == gridIndex ) { filter->updateCompundFilter( cellRangeFilter ); } diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.h b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.h index b330aa4b69..76d45ff75e 100644 --- a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.h +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterCollection.h @@ -68,6 +68,8 @@ public: void connectToFilterUpdates( RimCellFilter* filter ); + void setCase( RimCase* theCase ); + protected: // Overridden methods void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterIntervalTool.cpp b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterIntervalTool.cpp new file mode 100644 index 0000000000..e552a1b029 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterIntervalTool.cpp @@ -0,0 +1,125 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021 Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimCellFilterIntervalTool.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCellFilterInterval::RimCellFilterInterval( size_t minIncludeVal, size_t maxIncludeVal ) + : m_minIncludeVal( minIncludeVal ) + , m_maxIncludeVal( maxIncludeVal ) +{ + m_valid = maxIncludeVal >= minIncludeVal; + m_valid = m_valid && minIncludeVal > 0; +} + +RimCellFilterInterval::RimCellFilterInterval( size_t includeVal ) + : m_minIncludeVal( includeVal ) + , m_maxIncludeVal( includeVal ) +{ + m_valid = includeVal > 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCellFilterInterval::~RimCellFilterInterval() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimCellFilterInterval::isIncluded( size_t val ) const +{ + if ( ( val >= m_minIncludeVal ) && ( val <= m_maxIncludeVal ) ) return m_valid; + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCellFilterIntervalTool::RimCellFilterIntervalTool( bool includeAllByDefault ) + : m_includeAllByDefault( includeAllByDefault ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCellFilterIntervalTool::~RimCellFilterIntervalTool() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimCellFilterIntervalTool::isNumberIncluded( size_t number ) const +{ + if ( m_intervals.size() == 0 ) return m_includeAllByDefault; + + number = number + 1; + + for ( const auto& interval : m_intervals ) + { + if ( interval.isIncluded( number ) ) return true; + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimCellFilterIntervalTool::numberFromPart( QString strVal ) const +{ + return strVal.toUInt(); +} + +//-------------------------------------------------------------------------------------------------- +/// +// Define a range with the comma separated format A,B,C-D, etc., i.e. 1,4,5-8 +// Only positive numbers are supported. +//-------------------------------------------------------------------------------------------------- +void RimCellFilterIntervalTool::setInterval( bool enabled, QString intervalText ) +{ + m_intervals.clear(); + + if ( !enabled ) return; + + QStringList parts = intervalText.split( ',', QString::SkipEmptyParts ); + + for ( auto& part : parts ) + { + QStringList minmax = part.split( '-', QString::SkipEmptyParts ); + switch ( minmax.size() ) + { + case 1: + m_intervals.push_back( RimCellFilterInterval( numberFromPart( minmax[0] ) ) ); + break; + case 2: + m_intervals.push_back( RimCellFilterInterval( numberFromPart( minmax[0] ), numberFromPart( minmax[1] ) ) ); + break; + + default: + break; + } + } +} diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterIntervalTool.h b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterIntervalTool.h new file mode 100644 index 0000000000..3935ff4fc6 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/RimCellFilterIntervalTool.h @@ -0,0 +1,55 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021 Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + +class RimCellFilterInterval +{ +public: + RimCellFilterInterval( size_t minIncludeVal, size_t maxIncludeVal ); + RimCellFilterInterval( size_t includeVal ); + ~RimCellFilterInterval(); + + bool isIncluded( size_t val ) const; + +private: + size_t m_minIncludeVal; + size_t m_maxIncludeVal; + bool m_valid; +}; + +class RimCellFilterIntervalTool +{ +public: + RimCellFilterIntervalTool( bool includeAllByDefault = true ); + ~RimCellFilterIntervalTool(); + + void setInterval( bool enabled, QString intervalText ); + bool isNumberIncluded( size_t number ) const; + +private: + size_t numberFromPart( QString strVal ) const; + + bool m_includeAllByDefault; + QString m_intervalText; + + std::list m_intervals; +}; diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/RimPolygonFilter.cpp b/ApplicationLibCode/ProjectDataModel/CellFilters/RimPolygonFilter.cpp index c495e61d59..7ff88b62ae 100644 --- a/ApplicationLibCode/ProjectDataModel/CellFilters/RimPolygonFilter.cpp +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/RimPolygonFilter.cpp @@ -25,6 +25,7 @@ #include "RigFemPartGrid.h" #include "RigGeoMechCaseData.h" #include "RigMainGrid.h" +#include "RigPolyLinesData.h" #include "Rim3dView.h" #include "RimCase.h" @@ -38,14 +39,20 @@ #include "RiuViewerCommands.h" +#include "RiaStdStringTools.h" + #include "cafCmdFeatureMenuBuilder.h" +#include "cafPdmUiLineEditor.h" #include "cafPdmUiPushButtonEditor.h" #include "cafPdmUiTableViewEditor.h" #include "cafPdmUiTreeOrdering.h" +#include #include "cvfBoundingBox.h" #include "cvfStructGrid.h" +#include + namespace caf { template <> @@ -67,6 +74,42 @@ void caf::AppEnum::setUp() } // namespace caf +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class ThicknessValidator : public QValidator +{ +public: + State validate( QString& input, int& pos ) const override + { + if ( input.isEmpty() ) return State::Intermediate; + + int val = RiaStdStringTools::toInt( input.toStdString() ); + if ( val > 0 && val < 8 ) + return State::Acceptable; + else + return State::Invalid; + } +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class RadiusValidator : public QValidator +{ +public: + State validate( QString& input, int& pos ) const override + { + if ( input.isEmpty() ) return State::Intermediate; + + double val = RiaStdStringTools::toDouble( input.toStdString() ); + if ( val > 0.001 && val <= 2.0 ) + return State::Acceptable; + else + return State::Invalid; + } +}; + CAF_PDM_SOURCE_INIT( RimPolygonFilter, "PolygonFilter", "PolyLineFilter" ); //-------------------------------------------------------------------------------------------------- @@ -74,6 +117,7 @@ CAF_PDM_SOURCE_INIT( RimPolygonFilter, "PolygonFilter", "PolyLineFilter" ); //-------------------------------------------------------------------------------------------------- RimPolygonFilter::RimPolygonFilter() : m_pickTargetsEventHandler( new RicPolylineTargetsPickEventHandler( this ) ) + , m_intervalTool( true ) { CAF_PDM_InitObject( "Polyline Filter", ":/CellFilter_Polygon.png", "", "" ); @@ -94,6 +138,26 @@ RimPolygonFilter::RimPolygonFilter() CAF_PDM_InitFieldNoDefault( &m_srcCase, "Case", "Case", "", "", "" ); m_srcCase.uiCapability()->setUiHidden( true ); + CAF_PDM_InitField( &m_showLines, "ShowLines", true, "Show Lines", "", "", "" ); + CAF_PDM_InitField( &m_showSpheres, "ShowSpheres", false, "Show Spheres", "", "", "" ); + + CAF_PDM_InitField( &m_lineThickness, "LineThickness", 3, "Line Thickness", "", "", "" ); + CAF_PDM_InitField( &m_sphereRadiusFactor, "SphereRadiusFactor", 0.15, "Sphere Radius Factor", "", "", "" ); + + CAF_PDM_InitField( &m_lineColor, "LineColor", cvf::Color3f( cvf::Color3f::WHITE ), "Line Color", "", "", "" ); + CAF_PDM_InitField( &m_sphereColor, "SphereColor", cvf::Color3f( cvf::Color3f::WHITE ), "Sphere Color", "", "", "" ); + + CAF_PDM_InitField( &m_enableFiltering, "EnableFiltering", false, "Enable Filter", "", "", "" ); + + CAF_PDM_InitField( &m_enableKFilter, "EnableKFilter", false, "Enable K Range Filter", "", "", "" ); + CAF_PDM_InitFieldNoDefault( &m_kFilterStr, "KRangeFilter", "K Range Filter", "", "", "" ); + + CAF_PDM_InitField( &m_polygonPlaneDepth, "PolygonPlaneDepth", 0.0, "Polygon Plane Depth", "", "", "" ); + CAF_PDM_InitField( &m_lockPolygonToPlane, "LockPolygon", false, "Lock Polygon to Plane", "", "", "" ); + + m_polygonPlaneDepth.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() ); + m_polygonPlaneDepth.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosType::TOP ); + this->setUi3dEditorTypeName( RicPolyline3dEditor::uiEditorTypeName() ); this->uiCapability()->setUiTreeChildrenHidden( true ); @@ -142,12 +206,40 @@ void RimPolygonFilter::setCase( RimCase* srcCase ) m_srcCase = srcCase; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPolygonFilter::enableFilter( bool bEnable ) +{ + m_enableFiltering = bEnable; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPolygonFilter::enableKFilter( bool bEnable ) +{ + m_enableKFilter = bEnable; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimPolygonFilter::isFilterEnabled() const +{ + return m_isActive() && m_enableFiltering; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RimPolygonFilter::fullName() const { - return QString( "%1 [%2 cells]" ).arg( RimCellFilter::fullName(), QString::number( m_cells.size() ) ); + if ( m_enableFiltering ) + { + return QString( "%1 [%2 cells]" ).arg( RimCellFilter::fullName(), QString::number( m_cells.size() ) ); + } + return QString( "%1 [off]" ).arg( RimCellFilter::fullName() ); } //-------------------------------------------------------------------------------------------------- @@ -203,8 +295,7 @@ void RimPolygonFilter::defineEditorAttribute( const caf::PdmFieldHandle* field, } } } - - if ( field == &m_targets ) + else if ( field == &m_targets ) { auto tvAttribute = dynamic_cast( attribute ); if ( tvAttribute ) @@ -218,6 +309,41 @@ void RimPolygonFilter::defineEditorAttribute( const caf::PdmFieldHandle* field, } } } + else if ( field == &m_lineThickness ) + { + auto myAttr = dynamic_cast( attribute ); + if ( myAttr ) + { + myAttr->validator = new ThicknessValidator(); + } + } + else if ( field == &m_lineThickness ) + { + auto myAttr = dynamic_cast( attribute ); + if ( myAttr ) + { + myAttr->validator = new RadiusValidator(); + } + } + else if ( field == &m_polygonPlaneDepth ) + { + auto* attr = dynamic_cast( attribute ); + + if ( attr ) + { + if ( m_srcCase ) + { + auto bb = m_srcCase->allCellsBoundingBox(); + attr->m_minimum = -bb.max().z(); + attr->m_maximum = -bb.min().z(); + } + else + { + attr->m_minimum = 0; + attr->m_maximum = 10000; + } + } + } } //-------------------------------------------------------------------------------------------------- @@ -239,16 +365,54 @@ void RimPolygonFilter::defineCustomContextMenu( const caf::PdmFieldHandle* field //-------------------------------------------------------------------------------------------------- void RimPolygonFilter::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) { - RimCellFilter::defineUiOrdering( uiConfigName, uiOrdering ); + uiOrdering.add( &m_name ); - uiOrdering.add( &m_polyFilterMode ); - uiOrdering.add( &m_polyIncludeType ); - uiOrdering.add( &m_targets ); - uiOrdering.add( &m_enablePicking ); + auto group = uiOrdering.addNewGroup( "General" ); + group->add( &m_filterMode ); + group->add( &m_enableFiltering ); + group->add( &m_showLines ); + group->add( &m_showSpheres ); + + auto group1 = uiOrdering.addNewGroup( "Polygon Selection" ); + group1->add( &m_polyFilterMode ); + group1->add( &m_polyIncludeType ); + group1->add( &m_targets ); + group1->add( &m_enablePicking ); m_polyIncludeType.uiCapability()->setUiName( "Cells to " + modeString() ); + auto group2 = uiOrdering.addNewGroup( "Appearance" ); + if ( m_showLines ) + { + group2->add( &m_lineThickness ); + group2->add( &m_lineColor ); + } + if ( m_showSpheres ) + { + group2->add( &m_sphereRadiusFactor ); + group2->add( &m_sphereColor ); + } + group2->add( &m_lockPolygonToPlane ); + if ( m_lockPolygonToPlane ) group2->add( &m_polygonPlaneDepth ); + group2->setCollapsedByDefault( true ); + + auto group3 = uiOrdering.addNewGroup( "Advanced Filter Settings" ); + group3->add( &m_enableKFilter ); + group3->add( &m_kFilterStr ); + group3->add( &m_gridIndex ); + group3->add( &m_propagateToSubGrids ); + group3->setCollapsedByDefault( true ); + uiOrdering.skipRemainingFields( true ); + + bool readOnlyState = isFilterControlled(); + + std::vector objFields; + this->fields( objFields ); + for ( auto& objField : objFields ) + { + objField->uiCapability()->setUiReadOnly( readOnlyState ); + } } //-------------------------------------------------------------------------------------------------- @@ -264,7 +428,7 @@ void RimPolygonFilter::fieldChangedByUi( const caf::PdmFieldHandle* changedField if ( m_enablePicking() ) { - setActive( false ); + enableFilter( false ); filterChanged.send(); } } @@ -308,6 +472,8 @@ void RimPolygonFilter::updateCompundFilter( cvf::CellRangeFilter* cellRangeFilte { CVF_ASSERT( cellRangeFilter ); + if ( !m_enableFiltering ) return; + if ( m_cells.size() == 0 ) updateCells(); const auto grid = selectedGrid(); @@ -369,20 +535,25 @@ void RimPolygonFilter::updateCellsDepthEclipse( const std::vector& p { // we should look in depth using Z coordinate // loop over all cells - for ( size_t i = 0; i < grid->cellCount(); i++ ) + for ( size_t n = 0; n < grid->cellCount(); n++ ) { // valid cell? - RigCell cell = grid->cellByGridAndGridLocalCellIdx( gridIndex(), i ); + RigCell cell = grid->cellByGridAndGridLocalCellIdx( gridIndex(), n ); if ( cell.isInvalid() ) continue; // get corner coordinates std::array hexCorners; - grid->cellCornerVertices( i, hexCorners.data() ); + grid->cellCornerVertices( n, hexCorners.data() ); + + // get cell ijk for k filter + size_t i, j, k; + grid->ijkFromCellIndex( n, &i, &j, &k ); + if ( !m_intervalTool.isNumberIncluded( k ) ) continue; // check if the polygon includes the cell if ( cellInsidePolygon2D( cell.center(), hexCorners, points ) ) { - m_cells.push_back( i ); + m_cells.push_back( n ); } } } @@ -460,6 +631,8 @@ void RimPolygonFilter::updateCellsKIndexEclipse( const std::vector& for ( size_t k = 0; k < grid->cellCountK(); k++ ) { + if ( !m_intervalTool.isNumberIncluded( k ) ) continue; + // get the cell index size_t newIdx = grid->cellIndexFromIJK( ci, cj, k ); // valid cell? @@ -505,6 +678,8 @@ void RimPolygonFilter::updateCellsDepthGeoMech( const std::vector& p { for ( size_t k = 0; k < grid->cellCountK(); k++ ) { + if ( !m_intervalTool.isNumberIncluded( k ) ) continue; + size_t cellIdx = grid->cellIndexFromIJK( i, j, k ); cvf::Vec3d vertices[8]; @@ -608,6 +783,8 @@ void RimPolygonFilter::updateCellsKIndexGeoMech( const std::vector& for ( size_t k = 0; k < grid->cellCountK(); k++ ) { + if ( !m_intervalTool.isNumberIncluded( k ) ) continue; + // get the cell index size_t newIdx = grid->cellIndexFromIJK( ci, cj, k ); m_cells.push_back( newIdx ); @@ -643,6 +820,9 @@ void RimPolygonFilter::updateCells() // reset m_cells.clear(); + // get optional k-cell filter + m_intervalTool.setInterval( m_enableKFilter, m_kFilterStr ); + // get polyline as vector std::vector points; for ( auto& target : m_targets ) @@ -668,3 +848,32 @@ void RimPolygonFilter::updateCells() updateCellsForGeoMech( points, gCase ); } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RimPolygonFilter::polyLinesData() const +{ + cvf::ref pld = new RigPolyLinesData; + std::vector line; + for ( const RimPolylineTarget* target : m_targets ) + { + line.push_back( target->targetPointXYZ() ); + } + pld->setPolyLine( line ); + + pld->setLineAppearance( m_lineThickness, m_lineColor, true ); + pld->setSphereAppearance( m_sphereRadiusFactor, m_sphereColor ); + pld->setZPlaneLock( m_lockPolygonToPlane, -m_polygonPlaneDepth ); + + if ( isActive() ) + { + pld->setVisibility( m_showLines, m_showSpheres ); + } + else + { + pld->setVisibility( false, false ); + } + + return pld; +} diff --git a/ApplicationLibCode/ProjectDataModel/CellFilters/RimPolygonFilter.h b/ApplicationLibCode/ProjectDataModel/CellFilters/RimPolygonFilter.h index 5cb1adef4c..7c7eb0f207 100644 --- a/ApplicationLibCode/ProjectDataModel/CellFilters/RimPolygonFilter.h +++ b/ApplicationLibCode/ProjectDataModel/CellFilters/RimPolygonFilter.h @@ -19,16 +19,21 @@ #pragma once #include "RimCellFilter.h" +#include "RimCellFilterIntervalTool.h" #include "RimPolylinePickerInterface.h" +#include "RimPolylinesDataInterface.h" #include "cafAppEnum.h" #include "cafPdmChildArrayField.h" #include "cafPdmField.h" +#include "cafPdmFieldCvfColor.h" #include "cafPdmFieldCvfVec3d.h" #include "cafPdmObject.h" #include "cafPdmPtrField.h" #include "cafPickEventHandler.h" +#include "cvfColor3.h" + #include #include @@ -39,12 +44,13 @@ class RimEclipseCase; class RimGeoMechCase; class RigMainGrid; class RigFemPartGrid; +class RigPolylinesData; //================================================================================================== /// /// //================================================================================================== -class RimPolygonFilter : public RimCellFilter, public RimPolylinePickerInterface +class RimPolygonFilter : public RimCellFilter, public RimPolylinePickerInterface, public RimPolylinesDataInterface { CAF_PDM_HEADER_INIT; @@ -66,6 +72,10 @@ public: ~RimPolygonFilter() override; void setCase( RimCase* srcCase ); + void enableFilter( bool bEnable ); + void enableKFilter( bool bEnable ); + + bool isFilterEnabled() const override; void updateVisualization() override; void updateEditorsAndVisualization() override; @@ -79,6 +89,8 @@ public: void updateCompundFilter( cvf::CellRangeFilter* cellRangeFilter ) override; + cvf::ref polyLinesData() const override; + protected: void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; @@ -108,8 +120,21 @@ private: caf::PdmField> m_polyFilterMode; caf::PdmField> m_polyIncludeType; caf::PdmPtrField m_srcCase; + caf::PdmField m_enableFiltering; + caf::PdmField m_enableKFilter; + caf::PdmField m_showLines; + caf::PdmField m_showSpheres; + caf::PdmField m_kFilterStr; + caf::PdmField m_lineThickness; + caf::PdmField m_sphereRadiusFactor; + caf::PdmField m_lineColor; + caf::PdmField m_sphereColor; + caf::PdmField m_polygonPlaneDepth; + caf::PdmField m_lockPolygonToPlane; std::shared_ptr m_pickTargetsEventHandler; std::list m_cells; + + RimCellFilterIntervalTool m_intervalTool; }; diff --git a/ApplicationLibCode/ProjectDataModel/Rim3dView.cpp b/ApplicationLibCode/ProjectDataModel/Rim3dView.cpp index 2eb7a37327..634dcdecce 100644 --- a/ApplicationLibCode/ProjectDataModel/Rim3dView.cpp +++ b/ApplicationLibCode/ProjectDataModel/Rim3dView.cpp @@ -43,6 +43,7 @@ #include "RimWellPathCollection.h" #include "RivAnnotationsPartMgr.h" +#include "RivCellFilterPartMgr.h" #include "RivMeasurementPartMgr.h" #include "RivWellPathsPartMgr.h" @@ -170,8 +171,9 @@ Rim3dView::Rim3dView( void ) m_wellPathsPartManager = new RivWellPathsPartMgr( this ); m_annotationsPartManager = new RivAnnotationsPartMgr( this ); - + m_cellfilterPartManager = new RivCellFilterPartMgr( this ); m_measurementPartManager = new RivMeasurementPartMgr( this ); + this->setAs3DViewMdiWindow(); } @@ -570,12 +572,14 @@ void Rim3dView::updateDisplayModelForCurrentTimeStepAndRedraw() this->onUpdateDisplayModelForCurrentTimeStep(); appendAnnotationsToModel(); appendMeasurementToModel(); + appendCellFiltersToModel(); if ( Rim3dView* depView = prepareComparisonView() ) { depView->onUpdateDisplayModelForCurrentTimeStep(); depView->appendAnnotationsToModel(); depView->appendMeasurementToModel(); + depView->appendCellFiltersToModel(); restoreComparisonView(); } @@ -991,6 +995,19 @@ void Rim3dView::addAnnotationsToModel( cvf::ModelBasicList* annotationsModel ) annotationsModel->updateBoundingBoxesRecursive(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Rim3dView::addCellFiltersToModel( cvf::ModelBasicList* cellFilterModel ) +{ + if ( !this->ownerCase() ) return; + + cvf::ref transForm = displayCoordTransform(); + m_cellfilterPartManager->appendGeometryPartsToModel( cellFilterModel, transForm.p(), ownerCase()->allCellsBoundingBox() ); + + cellFilterModel->updateBoundingBoxesRecursive(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1529,6 +1546,28 @@ void Rim3dView::appendAnnotationsToModel() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Rim3dView::appendCellFiltersToModel() +{ + if ( !nativeOrOverrideViewer() ) return; + + cvf::Scene* frameScene = nativeOrOverrideViewer()->frame( m_currentTimeStep, isUsingOverrideViewer() ); + if ( frameScene ) + { + cvf::String name = "CellFilters"; + this->removeModelByName( frameScene, name ); + + cvf::ref model = new cvf::ModelBasicList; + model->setName( name ); + + addCellFiltersToModel( model.p() ); + + frameScene->addModel( model.p() ); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Rim3dView.h b/ApplicationLibCode/ProjectDataModel/Rim3dView.h index 3bf0e5513f..d494869e97 100644 --- a/ApplicationLibCode/ProjectDataModel/Rim3dView.h +++ b/ApplicationLibCode/ProjectDataModel/Rim3dView.h @@ -46,6 +46,7 @@ class RiuViewer; class RivAnnotationsPartMgr; class RivMeasurementPartMgr; class RivWellPathsPartMgr; +class RivCellFilterPartMgr; class RimViewNameConfig; namespace cvf @@ -192,6 +193,7 @@ protected: const cvf::BoundingBox& wellPathClipBoundingBox ); void addAnnotationsToModel( cvf::ModelBasicList* annotationsModel ); void addMeasurementToModel( cvf::ModelBasicList* measureModel ); + void addCellFiltersToModel( cvf::ModelBasicList* cellFilterModel ); // Override viewer @@ -277,6 +279,7 @@ private: void createHighlightAndGridBoxDisplayModel(); void appendAnnotationsToModel(); void appendMeasurementToModel(); + void appendCellFiltersToModel(); // Pure private methods : Override viewer and comparison view @@ -308,4 +311,5 @@ private: cvf::ref m_highlightVizModel; cvf::ref m_annotationsPartManager; cvf::ref m_measurementPartManager; + cvf::ref m_cellfilterPartManager; }; diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp index 5fca502a60..059373b24d 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseView.cpp @@ -1518,6 +1518,7 @@ void RimEclipseView::setEclipseCase( RimEclipseCase* reservoir ) m_eclipseCase = reservoir; cellResult()->setEclipseCase( reservoir ); faultResultSettings()->customFaultResult()->setEclipseCase( reservoir ); + cellFilterCollection()->setCase( reservoir ); cellEdgeResult()->setEclipseCase( reservoir ); } diff --git a/ApplicationLibCode/ProjectDataModel/RimGeoMechView.cpp b/ApplicationLibCode/ProjectDataModel/RimGeoMechView.cpp index e09559a8a4..83c895cf48 100644 --- a/ApplicationLibCode/ProjectDataModel/RimGeoMechView.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimGeoMechView.cpp @@ -434,6 +434,7 @@ void RimGeoMechView::setGeoMechCase( RimGeoMechCase* gmCase ) { m_geomechCase = gmCase; cellResult()->setGeoMechCase( gmCase ); + cellFilterCollection()->setCase( gmCase ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimPolylinesDataInterface.h b/ApplicationLibCode/ProjectDataModel/RimPolylinesDataInterface.h new file mode 100644 index 0000000000..c2115a0997 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/RimPolylinesDataInterface.h @@ -0,0 +1,29 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021 Equinor ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfObject.h" + +class RigPolyLinesData; + +class RimPolylinesDataInterface +{ +public: + virtual cvf::ref polyLinesData() const = 0; +}; diff --git a/ApplicationLibCode/ProjectDataModel/RimViewController.cpp b/ApplicationLibCode/ProjectDataModel/RimViewController.cpp index 0018ebd698..4706b45617 100644 --- a/ApplicationLibCode/ProjectDataModel/RimViewController.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimViewController.cpp @@ -1037,6 +1037,7 @@ void RimViewController::updateCellFilterOverrides( const RimCellFilter* changedF { RimGeoMechCase* gCase = depGeomView->geoMechCase(); polyDstFilter->setCase( gCase ); + polyDstFilter->enableKFilter( false ); } } } @@ -1068,6 +1069,7 @@ void RimViewController::updateCellFilterOverrides( const RimCellFilter* changedF { RimEclipseCase* eCase = depEclView->eclipseCase(); polyDstFilter->setCase( eCase ); + polyDstFilter->enableKFilter( false ); } } } diff --git a/ApplicationLibCode/ReservoirDataModel/RigPolyLinesData.cpp b/ApplicationLibCode/ReservoirDataModel/RigPolyLinesData.cpp index 91e7d207e6..1b932ec5ad 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigPolyLinesData.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigPolyLinesData.cpp @@ -1,7 +1,6 @@ -#include "RigPolyLinesData.h" ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2018- Equinor ASA +// Copyright (C) 2021 Equinor ASA // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -22,7 +21,16 @@ /// //-------------------------------------------------------------------------------------------------- RigPolyLinesData::RigPolyLinesData() + : m_showLines( true ) + , m_showSpheres( true ) + , m_lineThickness( 4 ) + , m_sphereRadiusFactor( 0.1 ) + , m_lockToZPlane( false ) + , m_lockedZValue( 0.0 ) + , m_closePolyline( true ) { + m_sphereColor.set( 200, 200, 200 ); + m_lineColor.set( 200, 200, 200 ); } //-------------------------------------------------------------------------------------------------- @@ -31,3 +39,144 @@ RigPolyLinesData::RigPolyLinesData() RigPolyLinesData::~RigPolyLinesData() { } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector>& RigPolyLinesData::polyLines() const +{ + return m_polylines; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigPolyLinesData::setPolyLines( const std::vector>& polyLines ) +{ + m_polylines = polyLines; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigPolyLinesData::setPolyLine( const std::vector& polyline ) +{ + m_polylines = { polyline }; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigPolyLinesData::addPolyLine( const std::vector& polyline ) +{ + m_polylines.push_back( polyline ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigPolyLinesData::setVisibility( bool showLines, bool showSpheres ) +{ + m_showLines = showLines; + m_showSpheres = showSpheres; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigPolyLinesData::setLineAppearance( int lineThickness, cvf::Color3f color, bool closePolyline ) +{ + m_lineThickness = lineThickness; + m_lineColor = color; + m_closePolyline = closePolyline; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigPolyLinesData::setSphereAppearance( double radiusFactor, cvf::Color3f color ) +{ + m_sphereRadiusFactor = radiusFactor; + m_sphereColor = color; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigPolyLinesData::showLines() const +{ + return m_showLines; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigPolyLinesData::showSpheres() const +{ + return m_showSpheres; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RigPolyLinesData::lineThickness() const +{ + return m_lineThickness; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RigPolyLinesData::lineColor() const +{ + return m_lineColor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigPolyLinesData::closePolyline() const +{ + return m_closePolyline; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RigPolyLinesData::sphereColor() const +{ + return m_sphereColor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigPolyLinesData::sphereRadiusFactor() const +{ + return m_sphereRadiusFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigPolyLinesData::lockedZValue() const +{ + return m_lockedZValue; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigPolyLinesData::lockToZPlane() const +{ + return m_lockToZPlane; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigPolyLinesData::setZPlaneLock( bool lockToZ, double lockZValue ) +{ + m_lockToZPlane = lockToZ; + m_lockedZValue = lockZValue; +} diff --git a/ApplicationLibCode/ReservoirDataModel/RigPolyLinesData.h b/ApplicationLibCode/ReservoirDataModel/RigPolyLinesData.h index 759e3b03f8..89eeeb60e1 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigPolyLinesData.h +++ b/ApplicationLibCode/ReservoirDataModel/RigPolyLinesData.h @@ -18,6 +18,7 @@ #pragma once +#include "cvfColor3.h" #include "cvfObject.h" #include "cvfVector3.h" @@ -33,10 +34,40 @@ public: RigPolyLinesData(); ~RigPolyLinesData() override; - const std::vector>& polyLines() const { return m_polylines; } - void setPolyLines( const std::vector>& polyLines ) { m_polylines = polyLines; } - void setPolyLine( const std::vector& polyline ) { m_polylines = { polyline }; } + const std::vector>& polyLines() const; + + void setPolyLines( const std::vector>& polyLines ); + void setPolyLine( const std::vector& polyline ); + void addPolyLine( const std::vector& polyline ); + + void setVisibility( bool showLines, bool showSpheres ); + void setLineAppearance( int lineThickness, cvf::Color3f color, bool closePolyline ); + void setSphereAppearance( double radiusFactor, cvf::Color3f color ); + void setZPlaneLock( bool lockToZ, double lockZValue ); + + bool showLines() const; + bool showSpheres() const; + int lineThickness() const; + bool closePolyline() const; + cvf::Color3f lineColor() const; + cvf::Color3f sphereColor() const; + double sphereRadiusFactor() const; + double lockedZValue() const; + bool lockToZPlane() const; private: std::vector> m_polylines; + + bool m_showLines; + int m_lineThickness; + bool m_closePolyline; + + bool m_showSpheres; + double m_sphereRadiusFactor; + + bool m_lockToZPlane; + double m_lockedZValue; + + cvf::Color3f m_lineColor; + cvf::Color3f m_sphereColor; };