From a8b3ddc757afde1d6c894fc1720979ee966a8602 Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Mon, 29 Aug 2022 08:26:00 +0200 Subject: [PATCH] Thermal Fracture: rotate and place fracture according to template data. --- ...hermalFractureUsingTemplateDataFeature.cpp | 4 + .../Completions/RimFracture.cpp | 16 +++ .../Completions/RimFracture.h | 6 +- .../RimThermalFractureTemplate.cpp | 7 +- .../RigThermalFractureResultUtil.cpp | 99 ++++++++++++++++--- .../RigThermalFractureResultUtil.h | 4 + 6 files changed, 118 insertions(+), 18 deletions(-) diff --git a/ApplicationLibCode/Commands/FractureCommands/RicPlaceThermalFractureUsingTemplateDataFeature.cpp b/ApplicationLibCode/Commands/FractureCommands/RicPlaceThermalFractureUsingTemplateDataFeature.cpp index 91c66482e2..5391516504 100644 --- a/ApplicationLibCode/Commands/FractureCommands/RicPlaceThermalFractureUsingTemplateDataFeature.cpp +++ b/ApplicationLibCode/Commands/FractureCommands/RicPlaceThermalFractureUsingTemplateDataFeature.cpp @@ -70,6 +70,10 @@ void RicPlaceThermalFractureUsingTemplateDataFeature::onActionTriggered( bool is fracture->setMeasuredDepth( md ); + fracture->setAzimuth( rotation.x() ); + fracture->setDip( rotation.y() ); + fracture->setTilt( rotation.z() ); + fracture->updateConnectedEditors(); RimProject* project = RimProject::current(); project->reloadCompletionTypeResultsInAllViews(); diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.cpp index b0374dc1f8..a838824055 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.cpp @@ -543,6 +543,22 @@ double RimFracture::tilt() const return m_tilt(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFracture::setTilt( double tilt ) +{ + m_tilt = tilt; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFracture::setAzimuth( double azimuth ) +{ + m_azimuth = azimuth; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.h b/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.h index 34d8585f7d..7a1b10eff1 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimFracture.h @@ -97,7 +97,11 @@ public: cvf::Mat4d transformMatrix() const; void setDip( double dip ); double dip() const; - double tilt() const; + + void setTilt( double tilt ); + double tilt() const; + + void setAzimuth( double azimuth ); void setFractureTemplateNoUpdate( RimFractureTemplate* fractureTemplate ); void setFractureTemplate( RimFractureTemplate* fractureTemplate ); diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimThermalFractureTemplate.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimThermalFractureTemplate.cpp index 36d7df426e..dca38fe560 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimThermalFractureTemplate.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimThermalFractureTemplate.cpp @@ -695,13 +695,12 @@ QString RimThermalFractureTemplate::wellPathDepthAtFractureUiName() const //-------------------------------------------------------------------------------------------------- std::pair RimThermalFractureTemplate::computePositionAndRotation() const { - cvf::Vec3d centerPosition = cvf::Vec3d::UNDEFINED; - cvf::Vec3d rotation = cvf::Vec3d::UNDEFINED; - if ( m_fractureDefinitionData ) { - centerPosition = m_fractureDefinitionData->centerPosition(); + return RigThermalFractureResultUtil::computePositionAndRotation( m_fractureDefinitionData, m_activeTimeStepIndex ); } + cvf::Vec3d centerPosition = cvf::Vec3d::UNDEFINED; + cvf::Vec3d rotation = cvf::Vec3d::UNDEFINED; return std::make_pair( centerPosition, rotation ); } diff --git a/ApplicationLibCode/ReservoirDataModel/RigThermalFractureResultUtil.cpp b/ApplicationLibCode/ReservoirDataModel/RigThermalFractureResultUtil.cpp index b32af79043..e39ddf42ff 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigThermalFractureResultUtil.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigThermalFractureResultUtil.cpp @@ -30,10 +30,11 @@ #include "cafAssert.h" #include "cvfBoundingBox.h" +#include "cvfGeometryTools.h" #include -int numSamplesX = 60; +int numSamplesX = 100; int numSamplesY = 60; //-------------------------------------------------------------------------------------------------- @@ -365,16 +366,10 @@ std::pair, std::vector> double maxY = bb.max().y(); std::vector gridXs; - double sampleDistanceX = linearSampling( minX, maxX, numSamplesX, gridXs ); + linearSampling( minX, maxX, numSamplesX, gridXs ); std::vector gridYs; - double sampleDistanceY = linearSampling( minY, maxY, numSamplesY, gridYs ); - - RiaLogging::info( QString( "Uniform Mesh. Output size: %1x%2. Sampling Distance X = %3 Sampling Distance Y = %4" ) - .arg( numSamplesX ) - .arg( numSamplesY ) - .arg( sampleDistanceX ) - .arg( sampleDistanceY ) ); + linearSampling( minY, maxY, numSamplesY, gridYs ); return std::make_pair( gridXs, gridYs ); } @@ -481,13 +476,20 @@ std::vector std::vector relativePos = fractureDefinition->relativeCoordinates( static_cast( timeStepIndex ) ); CAF_ASSERT( relativePos.size() == fractureDefinition->numNodes() ); + for ( auto& r : relativePos ) + { + r.z() *= -1.0; + } + + cvf::Vec3d p0 = relativePos[0]; + cvf::Vec3d p1 = relativePos[1]; + cvf::Vec3d p2 = relativePos[2]; + cvf::Plane plane; - plane.setFromPoints( relativePos[0], relativePos[1], relativePos[2] ); + plane.setFromPoints( p0, p1, p2 ); cvf::Vec3d planeNormal = plane.normal().getNormalized(); - RiaLogging::info( - QString( "Plane normal: [%1 %2 %3]" ).arg( planeNormal.x() ).arg( planeNormal.y() ).arg( planeNormal.z() ) ); - auto rotMat = rotationMatrixBetweenVectors( planeNormal, cvf::Vec3d::Z_AXIS.getNormalized() ); + auto rotMat = rotationMatrixBetweenVectors( planeNormal, ( cvf::Vec3d::Z_AXIS ).getNormalized() ); for ( auto& r : relativePos ) { @@ -495,9 +497,80 @@ std::vector r.z() = 0.0; } + auto findExtrema = []( const std::vector& points ) { + double maxDistance = -1.0; + + cvf::Vec3d e1 = cvf::Vec3d::UNDEFINED; + cvf::Vec3d e2 = cvf::Vec3d::UNDEFINED; + for ( auto p1 : points ) + { + for ( auto p2 : points ) + { + double distance = p1.pointDistanceSquared( p2 ); + if ( distance > maxDistance ) + { + maxDistance = distance; + e1 = p1; + e2 = p2; + } + } + } + + return std::make_pair( e1, e2 ); + }; + + auto [e1, e2] = findExtrema( relativePos ); + cvf::Vec3d direction = e1 - e2; + auto rotMat2 = rotationMatrixBetweenVectors( direction.getNormalized(), cvf::Vec3d::X_AXIS ); + for ( auto& r : relativePos ) + { + r.transformVector( rotMat2 ); + } + return relativePos; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair RigThermalFractureResultUtil::computePositionAndRotation( + std::shared_ptr fractureDefinition, + size_t timeStepIndex ) +{ + std::vector relativePos = fractureDefinition->relativeCoordinates( static_cast( timeStepIndex ) ); + CAF_ASSERT( relativePos.size() == fractureDefinition->numNodes() ); + + cvf::Plane plane; + cvf::Vec3d p0 = relativePos[0]; + cvf::Vec3d p1 = relativePos[1]; + cvf::Vec3d p2 = relativePos[2]; + + p0.z() *= -1.0; + p1.z() *= -1.0; + p2.z() *= -1.0; + plane.setFromPoints( p0, p1, p2 ); + + cvf::Vec3d planeNormal = plane.normal().getNormalized(); + RiaLogging::info( + QString( "Plane normal: [%1 %2 %3]" ).arg( planeNormal.x() ).arg( planeNormal.y() ).arg( planeNormal.z() ) ); + + cvf::Plane xyPlane; + xyPlane.setFromPointAndNormal( cvf::Vec3d::ZERO, cvf::Vec3d::Z_AXIS ); + + cvf::Vec3d inPlane; + if ( !xyPlane.projectVector( planeNormal, &inPlane ) ) RiaLogging::info( "Failed to project vector" ); + + double azimuth = cvf::Math::toDegrees( cvf::GeometryTools::getAngle( inPlane, cvf::Vec3d::Y_AXIS ) ) + 90.0; + double dip = cvf::Math::toDegrees( cvf::GeometryTools::getAngle( inPlane, cvf::Vec3d::Z_AXIS ) ) - 90.0; + double tilt = cvf::Math::toDegrees( cvf::GeometryTools::getAngle( planeNormal, cvf::Vec3d::Z_AXIS ) ) - 90.0; + RiaLogging::info( QString( "Dip: %1" ).arg( dip ) ); + RiaLogging::info( QString( "Tilt: %1" ).arg( tilt ) ); + RiaLogging::info( QString( "Azimuth: %1" ).arg( azimuth ) ); + + cvf::Vec3d rotation( azimuth, dip, tilt ); + return std::make_pair( fractureDefinition->centerPosition(), rotation ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ReservoirDataModel/RigThermalFractureResultUtil.h b/ApplicationLibCode/ReservoirDataModel/RigThermalFractureResultUtil.h index 9e57ec3a27..05fd82f0a2 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigThermalFractureResultUtil.h +++ b/ApplicationLibCode/ReservoirDataModel/RigThermalFractureResultUtil.h @@ -86,6 +86,10 @@ public: static std::pair minMaxDepth( std::shared_ptr fractureDefinition, int activeTimeStepIndex ); + static std::pair + computePositionAndRotation( std::shared_ptr fractureDefinition, + size_t timeStepIndex ); + private: static std::pair, std::vector> generateUniformMesh( const cvf::BoundingBox& bb, int numSamplesX, int numSamplesY );