///////////////////////////////////////////////////////////////////////////////// // // 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 "RimWellPathCollection.h" #include "RiaApplication.h" #include "RiaPreferences.h" #include "RiaColorTables.h" #include "RigWellPath.h" #include "RimProject.h" #include "RimWellLogFile.h" #include "RimWellPath.h" #include "RiuMainWindow.h" #include "RivWellPathCollectionPartMgr.h" #include "RifWellPathImporter.h" #include "cafPdmUiEditorHandle.h" #include "cafProgressInfo.h" #include #include #include #include #include namespace caf { template<> void RimWellPathCollection::WellVisibilityEnum::setUp() { addItem(RimWellPathCollection::FORCE_ALL_OFF, "FORCE_ALL_OFF", "Off"); addItem(RimWellPathCollection::ALL_ON, "ALL_ON", "Individual"); addItem(RimWellPathCollection::FORCE_ALL_ON, "FORCE_ALL_ON", "On"); } } CAF_PDM_SOURCE_INIT(RimWellPathCollection, "WellPaths"); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimWellPathCollection::RimWellPathCollection() { CAF_PDM_InitObject("Wells", ":/WellCollection.png", "", ""); CAF_PDM_InitField(&isActive, "Active", true, "Active", "", "", ""); isActive.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&showWellPathLabel, "ShowWellPathLabel", true, "Show well path labels", "", "", ""); cvf::Color3f defWellLabelColor = RiaApplication::instance()->preferences()->defaultWellLabelColor(); CAF_PDM_InitField(&wellPathLabelColor, "WellPathLabelColor", defWellLabelColor, "Well label color", "", "", ""); CAF_PDM_InitField(&wellPathVisibility, "GlobalWellPathVisibility", WellVisibilityEnum(ALL_ON), "Global well path visibility", "", "", ""); CAF_PDM_InitField(&wellPathRadiusScaleFactor, "WellPathRadiusScale", 0.1, "Well Path radius scale", "", "", ""); CAF_PDM_InitField(&wellPathCrossSectionVertexCount, "WellPathVertexCount", 12, "Well Path vertex count", "", "", ""); wellPathCrossSectionVertexCount.xmlCapability()->setIOWritable(false); wellPathCrossSectionVertexCount.xmlCapability()->setIOReadable(false); wellPathCrossSectionVertexCount.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&wellPathClip, "WellPathClip", true, "Clip Well Paths", "", "", ""); CAF_PDM_InitField(&wellPathClipZDistance, "WellPathClipZDistance", 100, "Well path clipping depth distance", "", "", ""); CAF_PDM_InitFieldNoDefault(&wellPaths, "WellPaths", "Well Paths", "", "", ""); wellPaths.uiCapability()->setUiHidden(true); m_wellPathCollectionPartManager = new RivWellPathCollectionPartMgr(this); m_wellPathImporter = new RifWellPathImporter; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimWellPathCollection::~RimWellPathCollection() { wellPaths.deleteAllChildObjects(); delete m_wellPathImporter; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { scheduleGeometryRegenAndRedrawViews(); } //-------------------------------------------------------------------------------------------------- /// Read JSON files containing well path data //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::readWellPathFiles() { caf::ProgressInfo progress(wellPaths.size(), "Reading well paths from file"); for (size_t wpIdx = 0; wpIdx < wellPaths.size(); wpIdx++) { if (!wellPaths[wpIdx]->filepath().isEmpty()) { QString errorMessage; if (!wellPaths[wpIdx]->readWellPathFile(&errorMessage, m_wellPathImporter)) { QMessageBox::warning(RiuMainWindow::instance(), "File open error", errorMessage); } } RimWellLogFile* wellLogFile = wellPaths[wpIdx]->m_wellLogFile; if (wellLogFile) { QString errorMessage; if (!wellLogFile->readFile(&errorMessage)) { QString displayMessage = "Could not open the well log file: \n" + wellLogFile->fileName(); if (!errorMessage.isEmpty()) { displayMessage += "\n\n"; displayMessage += errorMessage; } QMessageBox::warning(RiuMainWindow::instance(), "File open error", displayMessage); } } progress.setProgressDescription(QString("Reading file %1").arg(wellPaths[wpIdx]->name)); progress.incrementProgress(); } this->sortWellsByName(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::addWellPaths( QStringList filePaths ) { std::vector wellPathArray; foreach (QString filePath, filePaths) { // Check if this file is already open bool alreadyOpen = false; for (size_t wpIdx = 0; wpIdx < wellPaths.size(); wpIdx++) { QFile f1; f1.setFileName(filePath); QString s1 = f1.fileName(); QFile f2; f2.setFileName(wellPaths[wpIdx]->filepath()); QString s2 = f2.fileName(); if (s1 == s2) { //printf("Attempting to open well path JSON file that is already open:\n %s\n", (const char*) filePath.toLocal8Bit()); alreadyOpen = true; break; } } if (!alreadyOpen) { QFileInfo fi(filePath); if (fi.suffix().compare("json") == 0) { RimWellPath* wellPath = new RimWellPath(); wellPath->filepath = filePath; wellPathArray.push_back(wellPath); } else { // Create Well path objects for all the paths in the assumed ascii file size_t wellPathCount = m_wellPathImporter->wellDataCount(filePath); for (size_t i = 0; i < wellPathCount; ++i) { RimWellPath* wellPath = new RimWellPath(); wellPath->filepath = filePath; wellPath->wellPathIndexInFile = static_cast(i); wellPathArray.push_back(wellPath); } } } } readAndAddWellPaths(wellPathArray); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::readAndAddWellPaths(std::vector& wellPathArray) { caf::ProgressInfo progress(wellPathArray.size(), "Reading well paths from file"); const caf::ColorTable& colorTable = RiaColorTables::wellLogPlotPaletteColors(); cvf::Color3ubArray wellColors = colorTable.color3ubArray(); cvf::Color3ubArray interpolatedWellColors = wellColors; if (wellPathArray.size() > 1) { interpolatedWellColors = caf::ColorTable::interpolateColorArray(wellColors, wellPathArray.size()); } for (size_t wpIdx = 0; wpIdx < wellPathArray.size(); wpIdx++) { RimWellPath* wellPath = wellPathArray[wpIdx]; wellPath->readWellPathFile(NULL, m_wellPathImporter); progress.setProgressDescription(QString("Reading file %1").arg(wellPath->name)); // If a well path with this name exists already, make it read the well path file RimWellPath* existingWellPath = wellPathByName(wellPath->name); if (existingWellPath) { existingWellPath->filepath = wellPath->filepath; existingWellPath->wellPathIndexInFile = wellPath->wellPathIndexInFile; existingWellPath->readWellPathFile(NULL, m_wellPathImporter); delete wellPath; } else { wellPath->wellPathColor = cvf::Color3f(interpolatedWellColors[wpIdx]); wellPaths.push_back(wellPath); } progress.incrementProgress(); } this->sortWellsByName(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::addWellLogs(const QStringList& filePaths) { foreach (QString filePath, filePaths) { RimWellLogFile* logFileInfo = RimWellLogFile::readWellLogFile(filePath); if (logFileInfo) { RimWellPath* wellPath = wellPathByName(logFileInfo->wellName()); if (!wellPath) { wellPath = new RimWellPath(); wellPaths.push_back(wellPath); } wellPath->setLogFileInfo(logFileInfo); } } this->sortWellsByName(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { caf::PdmUiGroup* wellHeadGroup = uiOrdering.addNewGroup("Well labels"); wellHeadGroup->add(&showWellPathLabel); wellHeadGroup->add(&wellPathLabelColor); caf::PdmUiGroup* wellPipe = uiOrdering.addNewGroup("Well pipe"); wellPipe->add(&wellPathVisibility); wellPipe->add(&wellPathRadiusScaleFactor); caf::PdmUiGroup* advancedGroup = uiOrdering.addNewGroup("Clipping"); advancedGroup->add(&wellPathClip); advancedGroup->add(&wellPathClipZDistance); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- caf::PdmFieldHandle* RimWellPathCollection::objectToggleField() { return &isActive; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::scheduleGeometryRegenAndRedrawViews() { m_wellPathCollectionPartManager->scheduleGeometryRegen(); RimProject* proj; this->firstAncestorOrThisOfType(proj); if (proj) proj->createDisplayModelAndRedrawAllViews(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) { for (size_t wellPathIdx = 0; wellPathIdx < wellPaths.size(); wellPathIdx++) { wellPaths[wellPathIdx]->updateFilePathsFromProjectPath(newProjectPath, oldProjectPath); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimWellPath* RimWellPathCollection::wellPathByName(const QString& wellPathName) const { for (size_t wellPathIdx = 0; wellPathIdx < wellPaths.size(); wellPathIdx++) { if (wellPaths[wellPathIdx]->name() == wellPathName) { return wellPaths[wellPathIdx]; } } return NULL; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::deleteAllWellPaths() { wellPaths.deleteAllChildObjects(); m_wellPathImporter->clear(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::removeWellPath(RimWellPath* wellPath) { wellPaths.removeChildObject(wellPath); bool isFilePathUsed = false; for (size_t i = 0; i < wellPaths.size(); i++) { if (wellPaths[i]->filepath == wellPath->filepath) { isFilePathUsed = true; break; } } if (!isFilePathUsed) { // One file can have multiple well paths // If no other well paths are referencing the filepath, remove cached data from the file reader m_wellPathImporter->removeFilePath(wellPath->filepath); } } bool lessWellPath(const caf::PdmPointer& w1, const caf::PdmPointer& w2) { if (w1.notNull() && w2.notNull()) return (w1->name() < w2->name()); else if (w1.notNull()) return true; else return false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::sortWellsByName() { std::sort(wellPaths.begin(), wellPaths.end(), lessWellPath); }