From 90d4c2f9d32cebed5e95a864dfddab1e77fc7da5 Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Fri, 9 Oct 2020 08:38:18 +0200 Subject: [PATCH] More hierarchical work --- .../Application/Tools/RiaFilePathTools.cpp | 2 +- .../Application/Tools/RiaTextStringTools.cpp | 13 +++- .../Application/Tools/RiaTextStringTools.h | 3 +- .../AnalysisPlots/RimAnalysisPlot.cpp | 5 +- .../RimParameterResultCrossPlot.cpp | 2 +- .../ProjectDataModel/RimWellPath.cpp | 24 +++++++ .../ProjectDataModel/RimWellPath.h | 12 ++-- .../RimWellPathCollection.cpp | 35 ++++++++++ .../ProjectDataModel/RimWellPathCollection.h | 1 + .../ReservoirDataModel/RigWellPath.cpp | 66 +++++++++++++++---- .../ReservoirDataModel/RigWellPath.h | 2 + 11 files changed, 141 insertions(+), 24 deletions(-) diff --git a/ApplicationCode/Application/Tools/RiaFilePathTools.cpp b/ApplicationCode/Application/Tools/RiaFilePathTools.cpp index 2b416d6353..ba7783abc9 100644 --- a/ApplicationCode/Application/Tools/RiaFilePathTools.cpp +++ b/ApplicationCode/Application/Tools/RiaFilePathTools.cpp @@ -192,7 +192,7 @@ QString RiaFilePathTools::commonRootOfFileNames( const QStringList& fileList ) QString fileNameWithoutExt = fileInfo.baseName(); fileNameList.push_back( fileNameWithoutExt ); } - QString root = RiaTextStringTools::findCommonRoot( fileNameList ); + QString root = RiaTextStringTools::commonRoot( fileNameList ); return root; } diff --git a/ApplicationCode/Application/Tools/RiaTextStringTools.cpp b/ApplicationCode/Application/Tools/RiaTextStringTools.cpp index d87167391b..926e714269 100644 --- a/ApplicationCode/Application/Tools/RiaTextStringTools.cpp +++ b/ApplicationCode/Application/Tools/RiaTextStringTools.cpp @@ -60,7 +60,7 @@ QString RiaTextStringTools::trimAndRemoveDoubleSpaces( const QString& s ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RiaTextStringTools::findCommonRoot( const QStringList& stringList ) +QString RiaTextStringTools::commonRoot( const QStringList& stringList ) { QString root = stringList.front(); for ( const auto& item : stringList ) @@ -82,3 +82,14 @@ QString RiaTextStringTools::findCommonRoot( const QStringList& stringList ) return root; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaTextStringTools::trimNonAlphaNumericCharacters( const QString& s ) +{ + QString trimmedString = s; + QRegularExpression trimRe( "[^a-zA-Z0-9]+$" ); + trimmedString.replace( trimRe, "" ); + return trimmedString; +} diff --git a/ApplicationCode/Application/Tools/RiaTextStringTools.h b/ApplicationCode/Application/Tools/RiaTextStringTools.h index 10d5829ae4..28f5804bd8 100644 --- a/ApplicationCode/Application/Tools/RiaTextStringTools.h +++ b/ApplicationCode/Application/Tools/RiaTextStringTools.h @@ -28,5 +28,6 @@ namespace RiaTextStringTools { bool compare( const QString& expected, const QString& actual ); QString trimAndRemoveDoubleSpaces( const QString& s ); -QString findCommonRoot( const QStringList& stringList ); +QString commonRoot( const QStringList& stringList ); +QString trimNonAlphaNumericCharacters( const QString& s ); } // namespace RiaTextStringTools diff --git a/ApplicationCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.cpp b/ApplicationCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.cpp index 727112aad7..1fc920713c 100644 --- a/ApplicationCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.cpp +++ b/ApplicationCode/ProjectDataModel/AnalysisPlots/RimAnalysisPlot.cpp @@ -1608,9 +1608,8 @@ void RimAnalysisPlot::updatePlotTitle() } } - QString root = RiaTextStringTools::findCommonRoot( caseNameList ); - QRegularExpression trimRe( "[^a-zA-Z0-9]+$" ); - QString trimmedRoot = root.replace( trimRe, "" ); + QString root = RiaTextStringTools::commonRoot( caseNameList ); + QString trimmedRoot = RiaTextStringTools::trimNonAlphaNumericCharacters( root ); if ( !trimmedRoot.isEmpty() ) { autoTitle += trimmedRoot; diff --git a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimParameterResultCrossPlot.cpp b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimParameterResultCrossPlot.cpp index 3294bc6234..cdc1eb307d 100644 --- a/ApplicationCode/ProjectDataModel/CorrelationPlots/RimParameterResultCrossPlot.cpp +++ b/ApplicationCode/ProjectDataModel/CorrelationPlots/RimParameterResultCrossPlot.cpp @@ -250,7 +250,7 @@ void RimParameterResultCrossPlot::createPoints() if ( !( parameter.isNumeric() && parameter.isValid() ) ) return; QStringList caseNames = caseNamesOfValidEnsembleCases( ensemble ); - QString commonCaseRoot = RiaTextStringTools::findCommonRoot( caseNames ); + QString commonCaseRoot = RiaTextStringTools::commonRoot( caseNames ); for ( size_t caseIdx = 0u; caseIdx < ensemble->allSummaryCases().size(); ++caseIdx ) { diff --git a/ApplicationCode/ProjectDataModel/RimWellPath.cpp b/ApplicationCode/ProjectDataModel/RimWellPath.cpp index 6252681d96..6152b6ac56 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPath.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPath.cpp @@ -371,6 +371,22 @@ void RimWellPath::addChildWellPath( RimWellPath* wellPath ) m_childWellPaths.push_back( wellPath ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPath::childWellPaths() const +{ + return m_childWellPaths.childObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimWellPath::childWellpathCount() const +{ + return m_childWellPaths.size(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -387,6 +403,14 @@ void RimWellPath::removeChildWellPath( RimWellPath* wellPath ) m_childWellPaths.removeChildObject( wellPath ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPath::removeAllChildWellPaths() +{ + m_childWellPaths.clear(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimWellPath.h b/ApplicationCode/ProjectDataModel/RimWellPath.h index 7b141bc0f4..489b09ab83 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPath.h +++ b/ApplicationCode/ProjectDataModel/RimWellPath.h @@ -92,13 +92,17 @@ public: RigWellPath* wellPathGeometry(); const RigWellPath* wellPathGeometry() const; + void setWellPathGeometry( RigWellPath* wellPathModel ); double startMD() const override; double endMD() const override; - void addChildWellPath( RimWellPath* wellPath ); - bool hasChildWellPath( RimWellPath* wellPath ); - void removeChildWellPath( RimWellPath* wellPath ); + void addChildWellPath( RimWellPath* wellPath ); + std::vector childWellPaths() const; + size_t childWellpathCount() const; + bool hasChildWellPath( RimWellPath* wellPath ); + void removeChildWellPath( RimWellPath* wellPath ); + void removeAllChildWellPaths(); void addWellLogFile( RimWellLogFile* logFileInfo ); void deleteWellLogFile( RimWellLogFile* logFileInfo ); @@ -160,8 +164,6 @@ protected: void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName ) override; - void setWellPathGeometry( RigWellPath* wellPathModel ); - // Fields protected: caf::PdmProxyValueField m_airGap; diff --git a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp index d4f743346d..1150b6d311 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp @@ -25,6 +25,7 @@ #include "RiaGuiApplication.h" #include "RiaLogging.h" #include "RiaPreferences.h" +#include "RiaTextStringTools.h" #include "RiaWellNameComparer.h" #include "RigEclipseCaseData.h" @@ -269,6 +270,7 @@ void RimWellPathCollection::addWellPath( gsl::not_null wellPath ) if ( mainWellPath ) { mainWellPath->addChildWellPath( wellPath ); + createWellPathBranchFromExistingWellPath( mainWellPath ); } else { @@ -685,6 +687,39 @@ void RimWellPathCollection::sortWellsByName() std::sort( m_wellPaths.begin(), m_wellPaths.end(), lessWellPath ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCollection::createWellPathBranchFromExistingWellPath( RimWellPath* wellPath ) +{ + if ( wellPath->childWellpathCount() > 0u ) + { + auto childCopy = static_cast( + wellPath->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) ); + + childCopy->setWellPathGeometry( wellPath->wellPathGeometry() ); + wellPath->setWellPathGeometry( nullptr ); + + childCopy->removeAllChildWellPaths(); + wellPath->addChildWellPath( childCopy ); + + std::vector allGeometries; + QStringList allNames; + for ( const auto& childWellPath : wellPath->childWellPaths() ) + { + allGeometries.push_back( childWellPath->wellPathGeometry() ); + allNames.push_back( childWellPath->name() ); + } + + cvf::ref commonGeometry = new RigWellPath( RigWellPath::commonGeometry( allGeometries ) ); + QString commonName = RiaTextStringTools::commonRoot( allNames ); + QString trimmedCommonName = RiaTextStringTools::trimNonAlphaNumericCharacters( commonName ); + + wellPath->setWellPathGeometry( commonGeometry.p() ); + wellPath->setName( trimmedCommonName ); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimWellPathCollection.h b/ApplicationCode/ProjectDataModel/RimWellPathCollection.h index 08a9da56d5..c29fd32195 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathCollection.h +++ b/ApplicationCode/ProjectDataModel/RimWellPathCollection.h @@ -135,6 +135,7 @@ private: void readAndAddWellPaths( std::vector& wellPathArray ); void sortWellsByName(); + void createWellPathBranchFromExistingWellPath( RimWellPath* wellPath ); RimWellPath* findSuitableParentWellPath( gsl::not_null wellPath ) const; RiaEclipseUnitTools::UnitSystemType findUnitSystemForWellPath( const RimWellPath* wellPath ); diff --git a/ApplicationCode/ReservoirDataModel/RigWellPath.cpp b/ApplicationCode/ReservoirDataModel/RigWellPath.cpp index 779f865294..10ec4eeecb 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellPath.cpp +++ b/ApplicationCode/ReservoirDataModel/RigWellPath.cpp @@ -22,6 +22,8 @@ #include "cvfGeometryTools.h" #include "cvfPlane.h" +#include + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -348,27 +350,67 @@ double RigWellPath::identicalTubeLength( const RigWellPath& other ) const { const double eps = 1.0e-8; - size_t minimumVertices = std::min( m_wellPathPoints.size(), other.wellPathPoints().size() ); - if ( minimumVertices < 2u ) return 0.0; + size_t minimumVertexCount = std::min( m_wellPathPoints.size(), other.wellPathPoints().size() ); + if ( minimumVertexCount < 2u ) return 0.0; - size_t minimumSegments = minimumVertices - 1u; - - double identicalMD = 0.0; - for ( size_t segmentIndex = 0; segmentIndex < minimumSegments; ++segmentIndex ) + double identicalLength = 0.0; + if ( ( m_wellPathPoints.front() - other.wellPathPoints().front() ).length() < eps ) { - size_t vIndex1 = segmentIndex; - size_t vIndex2 = segmentIndex + 1u; - if ( ( m_wellPathPoints[vIndex1] - other.wellPathPoints()[vIndex1] ).length() < eps && - ( m_wellPathPoints[vIndex2] - other.wellPathPoints()[vIndex2] ).length() < eps ) + for ( size_t vIndex = 1; vIndex < minimumVertexCount; ++vIndex ) { - identicalMD = m_measuredDepths[vIndex2]; + if ( ( m_wellPathPoints[vIndex] - other.wellPathPoints()[vIndex] ).length() < eps ) + { + identicalLength = m_measuredDepths[vIndex]; + } + else + { + break; + } + } + } + return identicalLength; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWellPath RigWellPath::commonGeometry( const std::vector& allGeometries ) +{ + const double eps = 1.0e-8; + + if ( allGeometries.empty() ) + return RigWellPath(); + else if ( allGeometries.size() == 1u ) + return *allGeometries.front(); + + const RigWellPath* firstGeometry = allGeometries.front(); + + std::vector commonWellPathPoints; + std::vector commonMDs; + + for ( size_t vIndex = 0u; vIndex < firstGeometry->wellPathPoints().size(); ++vIndex ) + { + const cvf::Vec3d& firstGeometryVertex = firstGeometry->wellPathPoints()[vIndex]; + + bool allMatches = std::all_of( allGeometries.begin() + 1, allGeometries.end(), [=]( const RigWellPath* geometry ) { + if ( geometry->wellPathPoints().size() > vIndex ) + { + return ( firstGeometryVertex - geometry->wellPathPoints()[vIndex] ).length() < eps; + } + return false; + } ); + + if ( allMatches ) + { + commonWellPathPoints.push_back( firstGeometryVertex ); + commonMDs.push_back( firstGeometry->measuredDepths()[vIndex] ); } else { break; } } - return identicalMD; + return RigWellPath( commonWellPathPoints, commonMDs ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigWellPath.h b/ApplicationCode/ReservoirDataModel/RigWellPath.h index 9e58368cf7..4f2c220f96 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellPath.h +++ b/ApplicationCode/ReservoirDataModel/RigWellPath.h @@ -70,6 +70,8 @@ public: void twoClosestPoints( const cvf::Vec3d& position, cvf::Vec3d* p1, cvf::Vec3d* p2 ) const; double identicalTubeLength( const RigWellPath& otherWellPathGeometry ) const; + static RigWellPath commonGeometry( const std::vector& allGeometries ); + std::pair, std::vector> clippedPointSubset( double startMD, double endMD, double* horizontalLengthAlongWellToStartClipPoint = nullptr ) const;