diff --git a/ApplicationLibCode/ModelVisualization/Intersections/RivExtrudedCurveIntersectionGeometryGenerator.cpp b/ApplicationLibCode/ModelVisualization/Intersections/RivExtrudedCurveIntersectionGeometryGenerator.cpp index 95f8b403a7..74567dbd98 100644 --- a/ApplicationLibCode/ModelVisualization/Intersections/RivExtrudedCurveIntersectionGeometryGenerator.cpp +++ b/ApplicationLibCode/ModelVisualization/Intersections/RivExtrudedCurveIntersectionGeometryGenerator.cpp @@ -145,7 +145,7 @@ void RivExtrudedCurveIntersectionGeometryGenerator::calculateLineSegementTransfo //-------------------------------------------------------------------------------------------------- void RivExtrudedCurveIntersectionGeometryGenerator::calculateTransformedPolyline() { - CVF_ASSERT( m_lineSegmentTransforms.size() == m_polylines.size() ); + if ( m_lineSegmentTransforms.size() != m_polylines.size() ) return; for ( size_t lineIdx = 0; lineIdx < m_polylines.size(); ++lineIdx ) { @@ -289,6 +289,30 @@ void RivExtrudedCurveIntersectionGeometryGenerator::calculateArrays() calculateLineSegementTransforms(); calculateTransformedPolyline(); + const double gridRadius = gridBBox.radius(); + + // set up our horizontal cut planes + const double topDepth = -1.0 * m_intersection->topDepth( gridRadius ); + const double bottomDepth = -1.0 * m_intersection->bottomDepth( gridRadius ); + + std::array corners; + gridBBox.cornerVertices( corners.data() ); + + cvf::Vec3d p1_low( corners[0].x(), corners[0].y(), bottomDepth ); + cvf::Vec3d p2_low( corners[1].x(), corners[1].y(), bottomDepth ); + cvf::Vec3d p3_low( corners[2].x(), corners[2].y(), bottomDepth ); + + cvf::Plane lowPlane; + lowPlane.setFromPoints( p1_low, p2_low, p3_low ); + + cvf::Vec3d p1_high( p1_low.x(), p1_low.y(), topDepth ); + cvf::Vec3d p2_high( p2_low.x(), p2_low.y(), topDepth ); + cvf::Vec3d p3_high( p3_low.x(), p3_low.y(), topDepth ); + + cvf::Plane highPlane; + highPlane.setFromPoints( p1_high, p2_high, p3_high ); + highPlane.flip(); + for ( size_t pLineIdx = 0; pLineIdx < m_polylines.size(); ++pLineIdx ) { const std::vector& polyLine = m_polylines[pLineIdx]; @@ -345,6 +369,9 @@ void RivExtrudedCurveIntersectionGeometryGenerator::calculateArrays() sectionBBox.add( p2 - maxHeightVec ); } + sectionBBox.cutBelow( bottomDepth ); + sectionBBox.cutAbove( topDepth ); + std::vector columnCellCandidates; m_hexGrid->findIntersectingCells( sectionBBox, &columnCellCandidates ); @@ -410,16 +437,32 @@ void RivExtrudedCurveIntersectionGeometryGenerator::calculateArrays() } } - std::vector clippedTriangleVxes; - std::vector cellFaceForEachClippedTriangleEdge; + std::vector clippedTriangleVxes_stage1; + std::vector cellFaceForEachClippedTriangleEdge_stage1; caf::HexGridIntersectionTools::clipTrianglesBetweenTwoParallelPlanes( hexPlaneCutTriangleVxes, cellFaceForEachTriangleEdge, p1Plane, p2Plane, + &clippedTriangleVxes_stage1, + &cellFaceForEachClippedTriangleEdge_stage1 ); + + for ( caf::HexGridIntersectionTools::ClipVx& clvx : clippedTriangleVxes_stage1 ) + if ( !clvx.isVxIdsNative ) clvx.derivedVxLevel = 0; + + std::vector clippedTriangleVxes; + std::vector cellFaceForEachClippedTriangleEdge; + + caf::HexGridIntersectionTools::clipTrianglesBetweenTwoParallelPlanes( clippedTriangleVxes_stage1, + cellFaceForEachClippedTriangleEdge_stage1, + lowPlane, + highPlane, &clippedTriangleVxes, &cellFaceForEachClippedTriangleEdge ); + for ( caf::HexGridIntersectionTools::ClipVx& clvx : clippedTriangleVxes ) + if ( !clvx.isVxIdsNative && clvx.derivedVxLevel == -1 ) clvx.derivedVxLevel = 1; + size_t clippedTriangleCount = clippedTriangleVxes.size() / 3; for ( uint tIdx = 0; tIdx < clippedTriangleCount; ++tIdx ) @@ -427,7 +470,6 @@ void RivExtrudedCurveIntersectionGeometryGenerator::calculateArrays() uint triVxIdx = tIdx * 3; // Accumulate triangle vertices - cvf::Vec3d point0( clippedTriangleVxes[triVxIdx + 0].vx ); cvf::Vec3d point1( clippedTriangleVxes[triVxIdx + 1].vx ); cvf::Vec3d point2( clippedTriangleVxes[triVxIdx + 2].vx ); @@ -441,13 +483,11 @@ void RivExtrudedCurveIntersectionGeometryGenerator::calculateArrays() triangleVertices.emplace_back( point2 ); // Accumulate mesh lines - meshAcc.accumulateMeshLines( cellFaceForEachClippedTriangleEdge, triVxIdx + 0, globalCellIdx, point0, point1 ); meshAcc.accumulateMeshLines( cellFaceForEachClippedTriangleEdge, triVxIdx + 1, globalCellIdx, point1, point2 ); meshAcc.accumulateMeshLines( cellFaceForEachClippedTriangleEdge, triVxIdx + 2, globalCellIdx, point2, point0 ); // Mapping to cell index - m_triangleToCellIdxMap.push_back( globalCellIdx ); // Interpolation from nodes @@ -462,16 +502,100 @@ void RivExtrudedCurveIntersectionGeometryGenerator::calculateArrays() } else { - caf::HexGridIntersectionTools::ClipVx cvx1 = hexPlaneCutTriangleVxes[cvx.clippedEdgeVx1Id]; - caf::HexGridIntersectionTools::ClipVx cvx2 = hexPlaneCutTriangleVxes[cvx.clippedEdgeVx2Id]; + caf::HexGridIntersectionTools::ClipVx cvx1; + caf::HexGridIntersectionTools::ClipVx cvx2; - m_triVxToCellCornerWeights.emplace_back( cvx1.clippedEdgeVx1Id, - cvx1.clippedEdgeVx2Id, - cvx1.normDistFromEdgeVx1, - cvx2.clippedEdgeVx1Id, - cvx2.clippedEdgeVx2Id, - cvx2.normDistFromEdgeVx1, - cvx.normDistFromEdgeVx1 ); + if ( cvx.derivedVxLevel == 0 ) + { + cvx1 = hexPlaneCutTriangleVxes[cvx.clippedEdgeVx1Id]; + cvx2 = hexPlaneCutTriangleVxes[cvx.clippedEdgeVx2Id]; + } + else if ( cvx.derivedVxLevel == 1 ) + { + cvx1 = clippedTriangleVxes_stage1[cvx.clippedEdgeVx1Id]; + cvx2 = clippedTriangleVxes_stage1[cvx.clippedEdgeVx2Id]; + } + else + { + CVF_ASSERT( false ); + } + + if ( cvx1.isVxIdsNative && cvx2.isVxIdsNative ) + { + m_triVxToCellCornerWeights.emplace_back( cvx1.clippedEdgeVx1Id, + cvx1.clippedEdgeVx2Id, + cvx1.normDistFromEdgeVx1, + cvx2.clippedEdgeVx1Id, + cvx2.clippedEdgeVx2Id, + cvx2.normDistFromEdgeVx1, + cvx.normDistFromEdgeVx1 ); + } + else + { + caf::HexGridIntersectionTools::ClipVx cvx11; + caf::HexGridIntersectionTools::ClipVx cvx12; + caf::HexGridIntersectionTools::ClipVx cvx21; + caf::HexGridIntersectionTools::ClipVx cvx22; + + if ( cvx1.isVxIdsNative ) + { + cvx11 = cvx1; + cvx12 = cvx1; + } + else if ( cvx1.derivedVxLevel == 0 ) + { + cvx11 = hexPlaneCutTriangleVxes[cvx1.clippedEdgeVx1Id]; + cvx12 = hexPlaneCutTriangleVxes[cvx1.clippedEdgeVx2Id]; + } + else if ( cvx2.derivedVxLevel == 1 ) + { + cvx11 = clippedTriangleVxes_stage1[cvx1.clippedEdgeVx1Id]; + cvx12 = clippedTriangleVxes_stage1[cvx1.clippedEdgeVx2Id]; + } + else + { + CVF_ASSERT( false ); + } + + if ( cvx2.isVxIdsNative ) + { + cvx21 = cvx2; + cvx22 = cvx2; + } + else if ( cvx2.derivedVxLevel == 0 ) + { + cvx21 = hexPlaneCutTriangleVxes[cvx2.clippedEdgeVx1Id]; + cvx22 = hexPlaneCutTriangleVxes[cvx2.clippedEdgeVx2Id]; + } + else if ( cvx2.derivedVxLevel == 1 ) + { + cvx21 = clippedTriangleVxes_stage1[cvx2.clippedEdgeVx1Id]; + cvx22 = clippedTriangleVxes_stage1[cvx2.clippedEdgeVx2Id]; + } + else + { + CVF_ASSERT( false ); + } + + CVF_TIGHT_ASSERT( cvx11.isVxIdsNative && cvx12.isVxIdsNative && cvx21.isVxIdsNative && + cvx22.isVxIdsNative ); + + m_triVxToCellCornerWeights.emplace_back( cvx11.clippedEdgeVx1Id, + cvx11.clippedEdgeVx2Id, + cvx11.normDistFromEdgeVx1, + cvx12.clippedEdgeVx1Id, + cvx12.clippedEdgeVx2Id, + cvx2.normDistFromEdgeVx1, + cvx21.clippedEdgeVx1Id, + cvx21.clippedEdgeVx2Id, + cvx21.normDistFromEdgeVx1, + cvx22.clippedEdgeVx1Id, + cvx22.clippedEdgeVx2Id, + cvx22.normDistFromEdgeVx1, + cvx1.normDistFromEdgeVx1, + cvx2.normDistFromEdgeVx1, + cvx.normDistFromEdgeVx1 ); + } } } } diff --git a/ApplicationLibCode/ProjectDataModel/Intersections/CMakeLists_files.cmake b/ApplicationLibCode/ProjectDataModel/Intersections/CMakeLists_files.cmake index 51adff8c51..35100c285e 100644 --- a/ApplicationLibCode/ProjectDataModel/Intersections/CMakeLists_files.cmake +++ b/ApplicationLibCode/ProjectDataModel/Intersections/CMakeLists_files.cmake @@ -5,6 +5,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RimIntersectionCollection.h ${CMAKE_CURRENT_LIST_DIR}/RimIntersectionResultDefinition.h ${CMAKE_CURRENT_LIST_DIR}/RimIntersectionResultsDefinitionCollection.h + ${CMAKE_CURRENT_LIST_DIR}/RimIntersectionEnums.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -14,6 +15,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RimIntersectionResultDefinition.cpp ${CMAKE_CURRENT_LIST_DIR}/RimIntersectionResultsDefinitionCollection.cpp ${CMAKE_CURRENT_LIST_DIR}/RimBoxIntersection.cpp + ${CMAKE_CURRENT_LIST_DIR}/RimIntersectionEnums.cpp ) list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/ProjectDataModel/Intersections/RimExtrudedCurveIntersection.cpp b/ApplicationLibCode/ProjectDataModel/Intersections/RimExtrudedCurveIntersection.cpp index 9ca5631d96..4dde235551 100644 --- a/ApplicationLibCode/ProjectDataModel/Intersections/RimExtrudedCurveIntersection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Intersections/RimExtrudedCurveIntersection.cpp @@ -22,6 +22,7 @@ #include "RiaVec3Tools.h" #include "RigEclipseCaseData.h" +#include "RigMainGrid.h" #include "RigWellPath.h" #include "Rim2dIntersectionView.h" @@ -46,13 +47,16 @@ #include "RimWellPath.h" #include "RiuViewer.h" + #include "RivExtrudedCurveIntersectionPartMgr.h" #include "cafCmdFeature.h" #include "cafCmdFeatureManager.h" +#include "cafPdmUiCheckBoxEditor.h" #include "cafPdmUiDoubleSliderEditor.h" #include "cafPdmUiListEditor.h" #include "cafPdmUiPushButtonEditor.h" +#include "cafPdmUiSliderEditor.h" #include "cafPdmUiTreeOrdering.h" #include "cafPdmUiTreeSelectionEditor.h" @@ -240,6 +244,26 @@ RimExtrudedCurveIntersection::RimExtrudedCurveIntersection() m_surfaceIntersections = new RimSurfaceIntersectionCollection; m_surfaceIntersections->objectChanged.connect( this, &RimExtrudedCurveIntersection::onSurfaceIntersectionsChanged ); + CAF_PDM_InitField( &m_depthThreshold, "DepthThreshold", 2000.0, "Threshold" ); + m_depthThreshold.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() ); + + CAF_PDM_InitFieldNoDefault( &m_depthDisplayType, "DepthDisplayType", "Intersection Display Type" ); + + CAF_PDM_InitFieldNoDefault( &m_collectionDepthThreshold, "CollectionDepthThreshold", "Collection Threshold" ); + m_collectionDepthThreshold.uiCapability()->setUiHidden( true ); + + CAF_PDM_InitField( &m_depthThresholdOverridden, + "ThresholdOverridden", + false, + "Depth Threshold is Controlled by Intersection Collection" ); + m_depthThresholdOverridden.uiCapability()->setUiReadOnly( true ); + caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_depthThresholdOverridden ); + + CAF_PDM_InitFieldNoDefault( &m_collectionDepthDisplayType, + "CollectionDepthDisplayType", + "Collection Controlled Display Type" ); + m_collectionDepthDisplayType.uiCapability()->setUiHidden( true ); + setDeletable( true ); } @@ -274,6 +298,56 @@ void RimExtrudedCurveIntersection::setName( const QString& newName ) m_name = newName; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimExtrudedCurveIntersection::topDepth( double sceneRadius ) const +{ + if ( m_depthThresholdOverridden ) + { + if ( m_collectionDepthDisplayType == RimIntersectionDepthCutEnum::INTERSECT_SHOW_BELOW ) + return m_collectionDepthThreshold; + return -sceneRadius; + } + + if ( m_depthDisplayType == RimIntersectionDepthCutEnum::INTERSECT_SHOW_BELOW ) + { + return m_depthThreshold; + } + return -sceneRadius; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimExtrudedCurveIntersection::bottomDepth( double sceneRadius ) const +{ + if ( m_depthThresholdOverridden ) + { + if ( m_collectionDepthDisplayType == RimIntersectionDepthCutEnum::INTERSECT_SHOW_ABOVE ) + return m_collectionDepthThreshold; + return sceneRadius; + } + + if ( m_depthDisplayType == RimIntersectionDepthCutEnum::INTERSECT_SHOW_ABOVE ) + { + return m_depthThreshold; + } + return sceneRadius; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimExtrudedCurveIntersection::setDepthOverride( bool collectionOverride, + double depthThreshold, + RimIntersectionDepthCutEnum displayType ) +{ + m_depthThresholdOverridden = collectionOverride; + m_collectionDepthThreshold = depthThreshold; + m_collectionDepthDisplayType = displayType; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -285,7 +359,7 @@ void RimExtrudedCurveIntersection::fieldChangedByUi( const caf::PdmFieldHandle* changedField == &m_wellPath || changedField == &m_simulationWell || changedField == &m_branchIndex || changedField == &m_extentLength || changedField == &m_lengthUp || changedField == &m_lengthDown || changedField == &m_showInactiveCells || changedField == &m_useSeparateDataSource || - changedField == &m_separateDataSource ) + changedField == &m_separateDataSource || changedField == &m_depthThreshold || changedField == &m_depthDisplayType ) { rebuildGeometryAndScheduleCreateDisplayModel(); } @@ -421,6 +495,21 @@ void RimExtrudedCurveIntersection::defineUiOrdering( QString uiConfigName, caf:: m_extentLength.uiCapability()->setUiReadOnly( false ); } + if ( eclipseView() ) + { + if ( m_depthThresholdOverridden() ) + { + optionsGroup->add( &m_depthThresholdOverridden ); + } + else + { + optionsGroup->add( &m_depthDisplayType ); + optionsGroup->add( &m_depthThreshold ); + m_depthThreshold.uiCapability()->setUiReadOnly( m_depthDisplayType() == + RimIntersectionDepthCutEnum ::INTERSECT_SHOW_ALL ); + } + } + this->defineSeparateDataSourceUi( uiConfigName, uiOrdering ); uiOrdering.skipRemainingFields( true ); @@ -506,12 +595,11 @@ void RimExtrudedCurveIntersection::defineUiTreeOrdering( caf::PdmUiTreeOrdering& //-------------------------------------------------------------------------------------------------- RimSimWellInViewCollection* RimExtrudedCurveIntersection::simulationWellCollection() const { - RimEclipseView* eclipseView = nullptr; - firstAncestorOrThisOfType( eclipseView ); + RimEclipseView* eclView = eclipseView(); - if ( eclipseView ) + if ( eclView ) { - return eclipseView->wellCollection(); + return eclView->wellCollection(); } return nullptr; @@ -833,6 +921,18 @@ void RimExtrudedCurveIntersection::defineEditorAttribute( const caf::PdmFieldHan doubleSliderAttrib->m_maximum = 180; doubleSliderAttrib->m_sliderTickCount = 180; } + else if ( field == &m_depthThreshold ) + { + RimEclipseView* eclView = eclipseView(); + + if ( eclView ) + { + const cvf::BoundingBox bb = eclView->mainGrid()->boundingBox(); + + doubleSliderAttrib->m_minimum = -1.0 * bb.max().z(); + doubleSliderAttrib->m_maximum = -1.0 * bb.min().z(); + } + } } else if ( field == &m_inputPolylineFromViewerEnabled ) { @@ -1149,3 +1249,13 @@ void RimExtrudedCurveIntersection::setPointsFromXYD( const std::vector pointsXYD() const; void setPointsFromXYD( const std::vector& pointsXYD ); + RimEclipseView* eclipseView() const; + private: caf::PdmField m_name; + caf::PdmField> m_depthDisplayType; + caf::PdmField m_depthThreshold; + + caf::PdmField m_depthThresholdOverridden; + caf::PdmField m_collectionDepthThreshold; + caf::PdmField> m_collectionDepthDisplayType; + caf::PdmField> m_type; caf::PdmField> m_direction; diff --git a/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersection.cpp b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersection.cpp index 7fe0da1f15..099ec20ab7 100644 --- a/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersection.cpp @@ -33,6 +33,8 @@ #include "RivEclipseIntersectionGrid.h" #include "RivFemIntersectionGrid.h" +#include "cafPdmUiCheckBoxEditor.h" + CAF_PDM_ABSTRACT_SOURCE_INIT( RimIntersection, "RimIntersectionHandle" ); //-------------------------------------------------------------------------------------------------- @@ -42,7 +44,10 @@ RimIntersection::RimIntersection() { CAF_PDM_InitField( &m_isActive, "Active", true, "Active" ); m_isActive.uiCapability()->setUiHidden( true ); + CAF_PDM_InitField( &m_showInactiveCells, "ShowInactiveCells", false, "Show Inactive Cells" ); + caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_showInactiveCells ); + CAF_PDM_InitField( &m_useSeparateDataSource, "UseSeparateIntersectionDataSource", true, "Enable" ); CAF_PDM_InitFieldNoDefault( &m_separateDataSource, "SeparateIntersectionDataSource", "Source" ); } diff --git a/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionCollection.cpp b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionCollection.cpp index d81a1fe9f7..3efe1dc6ee 100644 --- a/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionCollection.cpp @@ -19,11 +19,14 @@ #include "RimIntersectionCollection.h" +#include "RigMainGrid.h" + #include "Rim2dIntersectionView.h" #include "Rim2dIntersectionViewCollection.h" #include "Rim3dView.h" #include "RimBoxIntersection.h" #include "RimCase.h" +#include "RimEclipseView.h" #include "RimExtrudedCurveIntersection.h" #include "RimGridView.h" #include "RimIntersectionResultDefinition.h" @@ -35,6 +38,8 @@ #include "RivBoxIntersectionPartMgr.h" #include "RivExtrudedCurveIntersectionPartMgr.h" +#include "cafPdmUiCheckBoxEditor.h" +#include "cafPdmUiDoubleSliderEditor.h" #include "cafPdmUiTreeOrdering.h" #include "cvfModelBasicList.h" @@ -55,6 +60,14 @@ RimIntersectionCollection::RimIntersectionCollection() CAF_PDM_InitField( &isActive, "Active", true, "Active" ); isActive.uiCapability()->setUiHidden( true ); + + CAF_PDM_InitFieldNoDefault( &m_collectionDepthThreshold, "CollectionDepthThreshold", "Threshold" ); + m_collectionDepthThreshold.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() ); + + CAF_PDM_InitField( &m_depthThresholdOverridden, "ThresholdOverridden", false, "Override Intersection Display Settings" ); + caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_depthThresholdOverridden ); + + CAF_PDM_InitFieldNoDefault( &m_collectionDepthDisplayType, "CollectionDepthDisplayType", "Intersection Display Type" ); } //-------------------------------------------------------------------------------------------------- @@ -267,6 +280,8 @@ void RimIntersectionCollection::appendIntersectionAndUpdate( RimExtrudedCurveInt { m_intersections.push_back( intersection ); + intersection->setDepthOverride( m_depthThresholdOverridden, m_collectionDepthThreshold, m_collectionDepthDisplayType() ); + syncronize2dIntersectionViews(); updateConnectedEditors(); @@ -285,6 +300,7 @@ void RimIntersectionCollection::appendIntersectionAndUpdate( RimExtrudedCurveInt //-------------------------------------------------------------------------------------------------- void RimIntersectionCollection::appendIntersectionNoUpdate( RimExtrudedCurveIntersection* intersection ) { + intersection->setDepthOverride( m_depthThresholdOverridden, m_collectionDepthThreshold, m_collectionDepthDisplayType() ); m_intersections.push_back( intersection ); } @@ -349,6 +365,21 @@ void RimIntersectionCollection::fieldChangedByUi( const caf::PdmFieldHandle* cha { updateUiIconFromToggleField(); + Rim3dView* rimView = nullptr; + firstAncestorOrThisOfType( rimView ); + if ( rimView ) + { + rimView->scheduleCreateDisplayModelAndRedraw(); + } + } + if ( ( changedField == &m_collectionDepthThreshold ) || ( changedField == &m_depthThresholdOverridden ) || + ( changedField == &m_collectionDepthDisplayType ) ) + { + for ( RimExtrudedCurveIntersection* cs : m_intersections ) + { + cs->setDepthOverride( m_depthThresholdOverridden, m_collectionDepthThreshold, m_collectionDepthDisplayType() ); + } + Rim3dView* rimView = nullptr; firstAncestorOrThisOfType( rimView ); if ( rimView ) @@ -403,3 +434,57 @@ void RimIntersectionCollection::updateIntersectionBoxGeometry() intersectionBox->updateBoxManipulatorGeometry(); } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIntersectionCollection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) +{ + if ( eclipseView() ) + { + caf::PdmUiGroup* optionsGroup = uiOrdering.addNewGroup( "Curve Intersections" ); + + optionsGroup->add( &m_depthThresholdOverridden ); + optionsGroup->add( &m_collectionDepthDisplayType ); + optionsGroup->add( &m_collectionDepthThreshold ); + m_collectionDepthDisplayType.uiCapability()->setUiReadOnly( !m_depthThresholdOverridden() ); + m_collectionDepthThreshold.uiCapability()->setUiReadOnly( !m_depthThresholdOverridden() ); + } + + uiOrdering.skipRemainingFields( true ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIntersectionCollection::defineEditorAttribute( const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute ) +{ + auto* doubleSliderAttrib = dynamic_cast( attribute ); + if ( doubleSliderAttrib ) + { + if ( field == &m_collectionDepthThreshold ) + { + RimEclipseView* eclView = eclipseView(); + + if ( eclView ) + { + const cvf::BoundingBox bb = eclView->mainGrid()->boundingBox(); + + doubleSliderAttrib->m_minimum = -1.0 * bb.max().z(); + doubleSliderAttrib->m_maximum = -1.0 * bb.min().z(); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseView* RimIntersectionCollection::eclipseView() const +{ + RimEclipseView* eclipseView = nullptr; + firstAncestorOrThisOfType( eclipseView ); + return eclipseView; +} diff --git a/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionCollection.h b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionCollection.h index 7aa4e5f53e..5aea710d5c 100644 --- a/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionCollection.h +++ b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionCollection.h @@ -23,7 +23,10 @@ #include "cafPdmField.h" #include "cafPdmObject.h" +#include "RimIntersectionEnums.h" + class Rim3dView; +class RimEclipseView; class RimExtrudedCurveIntersection; class RimBoxIntersection; class RimEclipseCellColors; @@ -83,9 +86,20 @@ public: protected: void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; caf::PdmFieldHandle* objectToggleField() override; + void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override; + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + void defineEditorAttribute( const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute ) override; private: + RimEclipseView* eclipseView() const; + caf::PdmChildArrayField m_intersections; caf::PdmChildArrayField m_intersectionBoxes; + + caf::PdmField m_depthThresholdOverridden; + caf::PdmField m_collectionDepthThreshold; + caf::PdmField> m_collectionDepthDisplayType; }; diff --git a/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionEnums.cpp b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionEnums.cpp new file mode 100644 index 0000000000..f69d7cccbc --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionEnums.cpp @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RimIntersectionEnums.h" + +#include "cafAppEnum.h" + +namespace caf +{ +template <> +void caf::AppEnum::setUp() +{ + addItem( RimIntersectionDepthCutEnum::INTERSECT_SHOW_ALL, "INTERSECT_SHOW_ALL", "Show All" ); + addItem( RimIntersectionDepthCutEnum::INTERSECT_SHOW_ABOVE, "INTERSECT_SHOW_ABOVE", "Show Above Threshold" ); + addItem( RimIntersectionDepthCutEnum::INTERSECT_SHOW_BELOW, "INTERSECT_SHOW_BELOW", "Show Below Threshold" ); + setDefault( RimIntersectionDepthCutEnum::INTERSECT_SHOW_ALL ); +} + +} // namespace caf diff --git a/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionEnums.h b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionEnums.h new file mode 100644 index 0000000000..40dea9f248 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/Intersections/RimIntersectionEnums.h @@ -0,0 +1,26 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 + +enum class RimIntersectionDepthCutEnum +{ + INTERSECT_SHOW_ALL, + INTERSECT_SHOW_BELOW, + INTERSECT_SHOW_ABOVE +}; diff --git a/Fwk/VizFwk/LibGeometry/cvfBoundingBox.cpp b/Fwk/VizFwk/LibGeometry/cvfBoundingBox.cpp index ffb61848f8..486a125401 100644 --- a/Fwk/VizFwk/LibGeometry/cvfBoundingBox.cpp +++ b/Fwk/VizFwk/LibGeometry/cvfBoundingBox.cpp @@ -428,6 +428,29 @@ String BoundingBox::debugString() const return str; } +//-------------------------------------------------------------------------------------------------- +/// Cuts the box at the given depth, to never go below the given depth +/// +/// Note: cutting is a one time operation, adding new points to the box might extend the box below the cut depth +//-------------------------------------------------------------------------------------------------- +void BoundingBox::cutBelow(double depth) +{ + if (m_min.z() < depth) m_min.z() = depth; + if (m_max.z() < depth) m_max.z() = depth; +} + +//-------------------------------------------------------------------------------------------------- +/// Cuts the box at the given depth, to never go above the given depth +/// +/// Note: cutting is a one time operation, adding new points to the box might extend the box below the cut depth +//-------------------------------------------------------------------------------------------------- +void BoundingBox::cutAbove(double depth) +{ + if (m_min.z() > depth) m_min.z() = depth; + if (m_max.z() > depth) m_max.z() = depth; +} + + } // namespace cvf diff --git a/Fwk/VizFwk/LibGeometry/cvfBoundingBox.h b/Fwk/VizFwk/LibGeometry/cvfBoundingBox.h index d007379c2e..f2b02cda05 100644 --- a/Fwk/VizFwk/LibGeometry/cvfBoundingBox.h +++ b/Fwk/VizFwk/LibGeometry/cvfBoundingBox.h @@ -86,6 +86,9 @@ public: void transform(const Mat4d& matrix); const BoundingBox getTransformed(const Mat4d& matrix) const; + void cutBelow(double depth); + void cutAbove(double depth); + String debugString() const; private: