// // Copyright (C) 2011- Statoil ASA // Copyright (C) 2013- Ceetron Solutions AS // Copyright (C) 2011-2012 Ceetron AS // // 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 "RimTools.h" #include "RigFemPart.h" #include "RigFemPartCollection.h" #include "RigGeoMechCaseData.h" #include "RigReservoirGridTools.h" #include "RimCase.h" #include "RimColorLegend.h" #include "RimColorLegendCollection.h" #include "RimEclipseCase.h" #include "RimFaultInView.h" #include "RimFaultInViewCollection.h" #include "RimGeoMechCase.h" #include "RimOilField.h" #include "RimProject.h" #include "RimSeismicData.h" #include "RimSeismicDataCollection.h" #include "RimSeismicDifferenceData.h" #include "RimSurfaceCollection.h" #include "RimWellLogFile.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" #include "cafPdmUiItem.h" #include "cafUtils.h" #include #include #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RimTools::getCacheRootDirectoryPathFromProject() { if ( !RimProject::current() ) { return QString(); } QString projectFileName = RimProject::current()->fileName(); QString cacheRootFolderPath; QFileInfo fileInfo( projectFileName ); cacheRootFolderPath = fileInfo.canonicalPath(); cacheRootFolderPath += "/" + fileInfo.completeBaseName(); return cacheRootFolderPath; } //-------------------------------------------------------------------------------------------------- /// Relocate the supplied file name, based on the search path as follows: /// fileName, newProjectPath/fileNameWoPath, relocatedPath/fileNameWoPath /// If the file is not found in any of the positions, the fileName is returned but converted to Qt Style path /// separators: "/" /// /// The relocatedPath is found in this way: /// use the start of newProjectPath /// plus the end of the path to m_gridFileName /// such that the common start of oldProjectPath and m_gridFileName is removed from m_gridFileName /// and replaced with the start of newProjectPath up to where newProjectPath starts to be equal to oldProjectPath //-------------------------------------------------------------------------------------------------- QString RimTools::relocateFile( const QString& originalFileName, const QString& currentProjectPath, const QString& previousProjectPath, bool* foundFile, std::vector* searchedPaths ) { if ( foundFile ) *foundFile = true; // Make sure we have a Qt formatted path ( using "/" not "\") QString fileName = QDir::fromNativeSeparators( originalFileName ); QString newProjectPath = QDir::fromNativeSeparators( currentProjectPath ); QString oldProjectPath = QDir::fromNativeSeparators( previousProjectPath ); // If we from a file or whatever gets a real windows path on linux, we need to manually convert it // because Qt will not. QDir::fromNativeSeparators does nothing on linux. bool isWindowsPath = false; if ( originalFileName.count( "/" ) ) isWindowsPath = false; // "/" are not allowed in a windows path else if ( originalFileName.count( "\\" ) && !caf::Utils::fileExists( originalFileName ) ) // To make sure we do not // convert single linux // files containing "\" { isWindowsPath = true; } if ( isWindowsPath ) { // Windows absolute path detected. transform. fileName.replace( QString( "\\" ), QString( "/" ) ); } if ( searchedPaths ) searchedPaths->push_back( fileName ); if ( caf::Utils::fileExists( fileName ) ) { return fileName; } // First check in the new project file directory { QString fileNameWithoutPath = QFileInfo( fileName ).fileName(); QString candidate = QDir::fromNativeSeparators( newProjectPath + QDir::separator() + fileNameWithoutPath ); if ( searchedPaths ) searchedPaths->push_back( candidate ); if ( caf::Utils::fileExists( candidate ) ) { return candidate; } } // Then find the possible move of a directory structure where projects and files referenced are moved in "paralell" QFileInfo fileNameFileInfo( QDir::fromNativeSeparators( fileName ) ); QString fileNamePath = fileNameFileInfo.path(); QString fileNameWithoutPath = fileNameFileInfo.fileName(); QStringList fileNamePathElements = fileNamePath.split( "/" ); QString oldProjPath = QDir::fromNativeSeparators( oldProjectPath ); QStringList oldProjPathElements = oldProjPath.split( "/" ); QString newProjPath = QDir::fromNativeSeparators( newProjectPath ); QStringList newProjPathElements = newProjPath.split( "/" ); // Find the possible equal start of the old project path, and the referenced file bool pathStartsAreEqual = false; bool pathEndsDiffer = false; int firstDiffIdx = 0; for ( firstDiffIdx = 0; firstDiffIdx < fileNamePathElements.size() && firstDiffIdx < oldProjPathElements.size(); ++firstDiffIdx ) { #ifdef WIN32 // When comparing parts of a file path, the drive letter has been seen to be a mix of // upper and lower cases. Always use case insensitive compare on Windows, as this is a valid approach // for all parts for a file path Qt::CaseSensitivity cs = Qt::CaseInsensitive; #else Qt::CaseSensitivity cs = Qt::CaseSensitive; #endif if ( fileNamePathElements[firstDiffIdx].compare( oldProjPathElements[firstDiffIdx], cs ) == 0 ) { pathStartsAreEqual = pathStartsAreEqual || !fileNamePathElements[firstDiffIdx].isEmpty(); } else { pathEndsDiffer = true; break; } } if ( ( !pathEndsDiffer && firstDiffIdx < fileNamePathElements.size() ) || firstDiffIdx < oldProjPathElements.size() ) { pathEndsDiffer = true; } // If the path starts are equal, try to substitute it in the referenced file, with the corresponding new project // path start if ( pathStartsAreEqual ) { if ( pathEndsDiffer ) { QString oldFileNamePathEnd; for ( int i = firstDiffIdx; i < fileNamePathElements.size(); ++i ) { oldFileNamePathEnd += fileNamePathElements[i]; oldFileNamePathEnd += "/"; } // Find the new Project File Start Path QStringList oldProjectFilePathEndElements; for ( int i = firstDiffIdx; i < oldProjPathElements.size(); ++i ) { oldProjectFilePathEndElements.push_back( oldProjPathElements[i] ); } int lastProjectDiffIdx = newProjPathElements.size() - 1; { int ppIdx = oldProjectFilePathEndElements.size() - 1; for ( ; lastProjectDiffIdx >= 0 && ppIdx >= 0; --lastProjectDiffIdx, --ppIdx ) { if ( oldProjectFilePathEndElements[ppIdx] != newProjPathElements[lastProjectDiffIdx] ) { break; } } } QString newProjectFileStartPath; for ( int i = 0; i <= lastProjectDiffIdx; ++i ) { newProjectFileStartPath += newProjPathElements[i]; newProjectFileStartPath += "/"; } QString relocationPath = newProjectFileStartPath + oldFileNamePathEnd; QString relocatedFileName = relocationPath + fileNameWithoutPath; if ( searchedPaths ) searchedPaths->push_back( relocatedFileName ); if ( caf::Utils::fileExists( relocatedFileName ) ) { return relocatedFileName; } } else { // The Grid file was located in the same dir as the Project file. This is supposed to be handled above. // So we did not find it } } // return the unchanged filename, if we could not find a valid relocation file if ( foundFile ) *foundFile = false; return fileName; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::wellPathOptionItemsSubset( const std::vector& wellPathsToExclude, QList* options ) { if ( !options ) return; auto wellPathColl = RimTools::wellPathCollection(); if ( wellPathColl ) { std::vector wellPathsToInclude; auto all = wellPathColl->allWellPaths(); for ( auto w : all ) { bool include = true; for ( auto exclude : wellPathsToExclude ) { if ( w == exclude ) include = false; } if ( include ) wellPathsToInclude.push_back( w ); } optionItemsForSpecifiedWellPaths( wellPathsToInclude, options ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::wellPathOptionItems( QList* options ) { if ( !options ) return; auto wellPathColl = RimTools::wellPathCollection(); if ( wellPathColl ) { optionItemsForSpecifiedWellPaths( wellPathColl->allWellPaths(), options ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::wellPathWithFormationsOptionItems( QList* options ) { if ( !options ) return; std::vector wellPaths; RimTools::wellPathWithFormations( &wellPaths ); optionItemsForSpecifiedWellPaths( wellPaths, options ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::wellPathWithFormations( std::vector* wellPaths ) { auto wellPathColl = RimTools::wellPathCollection(); if ( wellPathColl ) { for ( RimWellPath* wellPath : wellPathColl->allWellPaths() ) { if ( wellPath->hasFormations() ) { wellPaths->push_back( wellPath ); } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::caseOptionItems( QList* options ) { if ( !options ) return; RimProject* proj = RimProject::current(); if ( proj ) { std::vector cases = proj->allGridCases(); for ( RimCase* c : cases ) { options->push_back( caf::PdmOptionItemInfo( c->caseUserDescription(), c, false, c->uiIconProvider() ) ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::eclipseCaseOptionItems( QList* options ) { if ( !options ) return; RimProject* proj = RimProject::current(); if ( proj ) { std::vector cases = proj->allGridCases(); for ( RimCase* c : cases ) { RimEclipseCase* eclipseCase = dynamic_cast( c ); if ( eclipseCase ) { options->push_back( caf::PdmOptionItemInfo( c->caseUserDescription(), c, false, c->uiIconProvider() ) ); } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::geoMechCaseOptionItems( QList* options ) { if ( !options ) return; RimProject* proj = RimProject::current(); if ( proj ) { std::vector cases = proj->allGridCases(); for ( RimCase* c : cases ) { RimGeoMechCase* geoMechCase = dynamic_cast( c ); if ( geoMechCase ) { options->push_back( caf::PdmOptionItemInfo( c->caseUserDescription(), c, false, c->uiIconProvider() ) ); } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::eclipseGridOptionItems( QList* options, RimEclipseCase* eCase ) { if ( !options ) return; for ( int gIdx = 0; gIdx < RigReservoirGridTools::gridCount( eCase ); gIdx++ ) { QString gridName = RigReservoirGridTools::gridName( eCase, gIdx ); if ( gIdx == 0 ) { if ( gridName.isEmpty() ) gridName += "Main Grid"; else gridName += " (Main Grid)"; } options->push_back( caf::PdmOptionItemInfo( gridName, gIdx ) ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::geoMechPartOptionItems( QList* options, RimGeoMechCase* gCase ) { if ( !options ) return; if ( !gCase || !gCase->geoMechData() || !gCase->geoMechData()->femParts() ) return; const auto parts = gCase->geoMechData()->femParts(); for ( int i = 0; i < parts->partCount(); i++ ) { auto part = parts->part( i ); if ( part != nullptr ) { options->push_back( caf::PdmOptionItemInfo( QString::fromStdString( part->name() ), i ) ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::geoMechElementSetOptionItems( QList* options, RimGeoMechCase* gCase, int partId ) { if ( !options ) return; if ( !gCase || !gCase->geoMechData() || !gCase->geoMechData()->femParts() ) return; const auto parts = gCase->geoMechData()->femParts(); if ( partId >= parts->partCount() ) return; auto part = parts->part( partId ); if ( part != nullptr ) { auto names = part->elementSetNames(); for ( int i = 0; i < (int)names.size(); i++ ) { options->push_back( caf::PdmOptionItemInfo( QString::fromStdString( names[i] ), i ) ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::seismicDataOptionItems( QList* options ) { if ( !options ) return; RimProject* proj = RimProject::current(); if ( proj ) { const auto& coll = proj->activeOilField()->seismicDataCollection().p(); for ( auto* c : coll->seismicData() ) { options->push_back( caf::PdmOptionItemInfo( QString::fromStdString( c->userDescription() ), c, false, c->uiIconProvider() ) ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::seismicDataOptionItems( QList* options, cvf::BoundingBox worldBBox, bool basicDataOnly ) { if ( !options ) return; RimProject* proj = RimProject::current(); if ( proj ) { const auto& coll = proj->activeOilField()->seismicDataCollection().p(); for ( auto* c : coll->seismicData() ) { if ( c->boundingBox()->intersects( worldBBox ) ) options->push_back( caf::PdmOptionItemInfo( QString::fromStdString( c->userDescription() ), c, false, c->uiIconProvider() ) ); } if ( !basicDataOnly ) { for ( auto* c : coll->differenceData() ) { if ( c->boundingBox()->intersects( worldBBox ) ) options->push_back( caf::PdmOptionItemInfo( QString::fromStdString( c->userDescription() ), c, false, c->uiIconProvider() ) ); } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::colorLegendOptionItems( QList* options ) { if ( !options ) return; RimProject* project = RimProject::current(); RimColorLegendCollection* colorLegendCollection = project->colorLegendCollection(); std::vector colorLegends = colorLegendCollection->allColorLegends(); for ( RimColorLegend* colorLegend : colorLegends ) { options->push_back( caf::PdmOptionItemInfo( colorLegend->colorLegendName(), colorLegend, false, colorLegend->paletteIconProvider() ) ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimWellPathCollection* RimTools::wellPathCollection() { RimProject* proj = RimProject::current(); if ( proj && proj->activeOilField() ) { return proj->activeOilField()->wellPathCollection(); } return nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimWellPath* RimTools::firstWellPath() { auto wellpathcoll = wellPathCollection(); auto wellpaths = wellpathcoll->allWellPaths(); if ( wellpaths.size() > 0 ) return wellpaths[0]; return nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimSurfaceCollection* RimTools::surfaceCollection() { RimProject* proj = RimProject::current(); return proj->activeOilField()->surfaceCollection(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::timeStepsForCase( RimCase* gridCase, QList* options ) { QStringList timeStepNames; if ( gridCase ) { timeStepNames = gridCase->timeStepStrings(); } for ( int i = 0; i < timeStepNames.size(); i++ ) { options->push_back( caf::PdmOptionItemInfo( timeStepNames[i], i ) ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::optionItemsForSpecifiedWellPaths( const std::vector& wellPaths, QList* options ) { if ( !options ) return; caf::IconProvider wellIcon( ":/Well.svg" ); for ( auto wellPath : wellPaths ) { options->push_back( caf::PdmOptionItemInfo( wellPath->name(), wellPath, false, wellIcon ) ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTools::faultOptionItems( QList* options, RimFaultInViewCollection* coll ) { if ( !options ) return; if ( !coll ) return; for ( auto& f : coll->faults() ) { options->push_back( caf::PdmOptionItemInfo( f->name(), f, false, f->uiIconProvider() ) ); } }