From c6964f583bcd54a80f5731469cb45b6bf88bef49 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 2 Aug 2018 14:03:35 +0200 Subject: [PATCH] #3090 Multi Fraction Creation : First working version --- .../FractureCommands/CMakeLists_files.cmake | 17 +- .../RicCreateMultipleFracturesFeature.cpp | 211 +++++++++++++ .../RicCreateMultipleFracturesFeature.h | 55 ++++ ...RicCreateMultipleFracturesOptionItemUi.cpp | 131 ++++++++ .../RicCreateMultipleFracturesOptionItemUi.h | 56 ++++ .../RicCreateMultipleFracturesUi.cpp | 290 ++++++++++++++++++ .../RicCreateMultipleFracturesUi.h | 86 ++++++ .../RicDeleteOptionItemFeature.cpp | 70 +++++ .../RicDeleteOptionItemFeature.h | 34 ++ .../RicNewOptionItemFeature.cpp | 78 +++++ .../RicNewOptionItemFeature.h | 34 ++ .../RimContextCommandBuilder.cpp | 3 + .../ProjectDataModel/RimDialogData.cpp | 12 + .../ProjectDataModel/RimDialogData.h | 32 +- 14 files changed, 1097 insertions(+), 12 deletions(-) create mode 100644 ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.cpp create mode 100644 ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.h create mode 100644 ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.cpp create mode 100644 ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.h create mode 100644 ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.cpp create mode 100644 ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.h create mode 100644 ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.cpp create mode 100644 ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.h create mode 100644 ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.cpp create mode 100644 ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.h diff --git a/ApplicationCode/Commands/FractureCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/FractureCommands/CMakeLists_files.cmake index 9abc019ecd..6ab4d73b0b 100644 --- a/ApplicationCode/Commands/FractureCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/FractureCommands/CMakeLists_files.cmake @@ -12,6 +12,12 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewSimWellFractureFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicNewStimPlanFractureTemplateFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathFractureAtPosFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathFractureFeature.h + +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesOptionItemUi.h +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesUi.h +${CMAKE_CURRENT_LIST_DIR}/RicNewOptionItemFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicDeleteOptionItemFeature.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -27,8 +33,13 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewSimWellFractureFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewStimPlanFractureTemplateFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathFractureAtPosFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathFractureFeature.cpp -) +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesOptionItemUi.cpp +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesUi.cpp +${CMAKE_CURRENT_LIST_DIR}/RicNewOptionItemFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicDeleteOptionItemFeature.cpp +) list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES} @@ -38,4 +49,8 @@ list(APPEND CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES} ) +list(APPEND QT_MOC_HEADERS +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesFeature.h +) + source_group( "CommandFeature\\Fracture" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake ) diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.cpp b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.cpp new file mode 100644 index 0000000000..cceb458948 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.cpp @@ -0,0 +1,211 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil 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 "RicCreateMultipleFracturesFeature.h" +#include "RicFractureNameGenerator.h" + +#include "RiaApplication.h" + +#include "RicCreateMultipleFracturesUi.h" + +#include "RimDialogData.h" +#include "RimFractureTemplate.h" +#include "RimProject.h" +#include "RimWellPath.h" +#include "RimWellPathFracture.h" +#include "RimWellPathFractureCollection.h" + +#include "Riu3DMainWindowTools.h" + +#include "cafPdmUiPropertyViewDialog.h" +#include "cafSelectionManagerTools.h" + +#include +#include + +CAF_CMD_SOURCE_INIT(RicCreateMultipleFracturesFeature, "RicCreateMultipleFracturesFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::slotDeleteAndAppendFractures() +{ + RiuCreateMultipleFractionsUi* multipleFractionsUi = this->multipleFractionsUi(); + if (!multipleFractionsUi) return; + + auto items = multipleFractionsUi->locationsForNewFractures(); + for (auto item : items) + { + if (item.wellPath) + { + RimWellPathFractureCollection* fractureCollection = item.wellPath->fractureCollection(); + fractureCollection->deleteFractures(); + } + } + + slotAppendFractures(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::slotAppendFractures() +{ + RiuCreateMultipleFractionsUi* multipleFractionsUi = this->multipleFractionsUi(); + if (!multipleFractionsUi) return; + + auto items = multipleFractionsUi->locationsForNewFractures(); + for (auto item : items) + { + if (item.wellPath) + { + RimWellPathFractureCollection* fractureCollection = item.wellPath->fractureCollection(); + + RimWellPathFracture* fracture = new RimWellPathFracture(); + fractureCollection->fractures.push_back(fracture); + + fracture->setFractureUnit(item.wellPath->unitSystem()); + fracture->setMeasuredDepth(item.measuredDepth); + fracture->setFractureTemplate(item.fractureTemplate); + + QString fractureName = RicFractureNameGenerator::nameForNewFracture(); + if (item.fractureTemplate) + { + fractureName = QString("%1_%2").arg(item.fractureTemplate->name()).arg(item.measuredDepth); + } + + fracture->setName(fractureName); + } + } + + RiaApplication* app = RiaApplication::instance(); + RimProject* proj = app->project(); + + proj->updateConnectedEditors(); + proj->reloadCompletionTypeResultsInAllViews(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::slotClose() +{ + if (m_dialog) + { + m_dialog->close(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::slotCancel() +{ + RiuCreateMultipleFractionsUi* multipleFractionsUi = this->multipleFractionsUi(); + if (multipleFractionsUi) + { + multipleFractionsUi->readObjectFromXmlString(m_copyOfObject, caf::PdmDefaultObjectFactory::instance()); + multipleFractionsUi->resolveReferencesRecursively(); + } + + slotClose(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::onActionTriggered(bool isChecked) +{ + m_dialog = nullptr; + + RiuCreateMultipleFractionsUi* multipleFractionsUi = this->multipleFractionsUi(); + if (multipleFractionsUi) + { + m_copyOfObject = multipleFractionsUi->writeObjectToXmlString(); + + caf::PdmUiPropertyViewDialog propertyDialog( + Riu3DMainWindowTools::mainWindowWidget(), multipleFractionsUi, "Create Multiple Fractions", ""); + + m_dialog = &propertyDialog; + + propertyDialog.resize(QSize(600, 400)); + + QDialogButtonBox* dialogButtonBox = propertyDialog.dialogButtonBox(); + + dialogButtonBox->clear(); + + { + QPushButton* pushButton = dialogButtonBox->addButton("Replace Fractures", QDialogButtonBox::ActionRole); + connect(pushButton, SIGNAL(clicked()), this, SLOT(slotDeleteAndAppendFractures())); + pushButton->setDefault(false); + pushButton->setAutoDefault(false); + } + + { + QPushButton* pushButton = dialogButtonBox->addButton("Append Fractures", QDialogButtonBox::ActionRole); + connect(pushButton, SIGNAL(clicked()), this, SLOT(slotAppendFractures())); + pushButton->setDefault(false); + pushButton->setAutoDefault(false); + } + + { + QPushButton* pushButton = dialogButtonBox->addButton("Cancel", QDialogButtonBox::ActionRole); + connect(pushButton, SIGNAL(clicked()), this, SLOT(slotCancel())); + pushButton->setDefault(false); + pushButton->setAutoDefault(false); + } + + { + QPushButton* pushButton = dialogButtonBox->addButton("Close", QDialogButtonBox::ActionRole); + connect(pushButton, SIGNAL(clicked()), this, SLOT(slotClose())); + pushButton->setDefault(false); + pushButton->setAutoDefault(false); + } + + propertyDialog.exec(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setIcon(QIcon(":/FractureTemplate16x16.png")); + actionToSetup->setText("Create Multiple Fractures"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCreateMultipleFracturesFeature::isCommandEnabled() +{ + std::vector selWells = caf::selectedObjectsByTypeStrict(); + return !selWells.empty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuCreateMultipleFractionsUi* RicCreateMultipleFracturesFeature::multipleFractionsUi() const +{ + RiaApplication* app = RiaApplication::instance(); + RimProject* proj = app->project(); + + return proj->dialogData()->multipleFractionsData(); +} diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.h b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.h new file mode 100644 index 0000000000..17fd5bdf00 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.h @@ -0,0 +1,55 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil 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 + +#include "cafCmdFeature.h" + +#include + +class RiuCreateMultipleFractionsUi; + +namespace caf { + class PdmUiPropertyViewDialog; +} + +//================================================================================================== +/// +//================================================================================================== +class RicCreateMultipleFracturesFeature : public caf::CmdFeature +{ + Q_OBJECT + CAF_CMD_HEADER_INIT; + +private slots: + void slotDeleteAndAppendFractures(); + void slotAppendFractures(); + void slotClose(); + void slotCancel(); + +private: + virtual void onActionTriggered(bool isChecked) override; + virtual void setupActionLook(QAction* actionToSetup) override; + virtual bool isCommandEnabled() override; + + RiuCreateMultipleFractionsUi* multipleFractionsUi() const; + +private: + QPointer m_dialog; + QString m_copyOfObject; +}; diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.cpp b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.cpp new file mode 100644 index 0000000000..c1b078da66 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.cpp @@ -0,0 +1,131 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil 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 "RicCreateMultipleFracturesOptionItemUi.h" + +#include "RiaApplication.h" + +#include "RicCreateMultipleFracturesUi.h" +#include "RimFractureTemplate.h" +#include "RimFractureTemplateCollection.h" +#include "RimOilField.h" +#include "RimProject.h" + +CAF_PDM_SOURCE_INIT(RicCreateMultipleFracturesOptionItemUi, "RiuMultipleFractionsOptions"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicCreateMultipleFracturesOptionItemUi::RicCreateMultipleFracturesOptionItemUi() +{ + CAF_PDM_InitField(&m_topK, "TopKLayer", 0, "Top K Layer", "", "", ""); + CAF_PDM_InitField(&m_baseK, "BaseKLayer", 0, "Base K Layer", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_fractureTemplate, "Template", "Template", "", "", ""); + CAF_PDM_InitField(&m_minSpacing, "MinSpacing", 300.0, "Spacing", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RicCreateMultipleFracturesOptionItemUi::topK() const +{ + return m_topK; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RicCreateMultipleFracturesOptionItemUi::baseK() const +{ + return m_baseK; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFractureTemplate* RicCreateMultipleFracturesOptionItemUi::fractureTemplate() const +{ + return m_fractureTemplate(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicCreateMultipleFracturesOptionItemUi::minimumSpacing() const +{ + return m_minSpacing; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCreateMultipleFracturesOptionItemUi::isKLayerContained(int k) const +{ + auto minMax = std::minmax(m_topK, m_baseK); + + if (k < minMax.first) return false; + if (k < minMax.second) return true; + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesOptionItemUi::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) +{ + RiuCreateMultipleFractionsUi* parent = nullptr; + this->firstAncestorOrThisOfType(parent); + if (parent) + { + parent->updateConnectedEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList + RicCreateMultipleFracturesOptionItemUi::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) +{ + QList options; + + RimProject* proj = RiaApplication::instance()->project(); + CVF_ASSERT(proj); + + if (fieldNeedingOptions == &m_fractureTemplate) + { + RimOilField* oilField = proj->activeOilField(); + if (oilField && oilField->fractureDefinitionCollection) + { + RimFractureTemplateCollection* fracDefColl = oilField->fractureDefinitionCollection(); + + for (RimFractureTemplate* fracDef : fracDefColl->fractureTemplates()) + { + QString displayText = fracDef->nameAndUnit(); + + options.push_back(caf::PdmOptionItemInfo(displayText, fracDef)); + } + } + } + + return options; +} diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.h b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.h new file mode 100644 index 0000000000..8339f28b2b --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.h @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil 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 + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +class RimFractureTemplate; + +//================================================================================================== +/// +//================================================================================================== +class RicCreateMultipleFracturesOptionItemUi : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicCreateMultipleFracturesOptionItemUi(); + + int topK() const; + int baseK() const; + RimFractureTemplate* fractureTemplate() const; + double minimumSpacing() const; + + bool isKLayerContained(int k) const; + +private: + virtual void + fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) override; + +private: + caf::PdmField m_topK; + caf::PdmField m_baseK; + caf::PdmPtrField m_fractureTemplate; + caf::PdmField m_minSpacing; +}; diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.cpp b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.cpp new file mode 100644 index 0000000000..cc15a8efe2 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.cpp @@ -0,0 +1,290 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil 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 "RicCreateMultipleFracturesUi.h" + +#include "RifEclipseDataTableFormatter.h" + +#include "RigEclipseCaseData.h" +#include "RigMainGrid.h" +#include "RigWellPath.h" + +#include "RimEclipseCase.h" +#include "RimFractureTemplate.h" +#include "RimTools.h" +#include "RimWellPath.h" + +#include "cafCmdFeatureMenuBuilder.h" +#include "cafPdmUiTableViewEditor.h" +#include "cafPdmUiTextEditor.h" +#include "cafSelectionManagerTools.h" + +#include "cvfBoundingBox.h" + +CAF_PDM_SOURCE_INIT(RiuCreateMultipleFractionsUi, "RiuCreateMultipleFractionsUi"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuCreateMultipleFractionsUi::RiuCreateMultipleFractionsUi() +{ + CAF_PDM_InitFieldNoDefault(&m_sourceCase, "SourceCase", "Case", "", "", ""); + + CAF_PDM_InitField(&m_minDistanceFromWellTd, "MinDistanceFromWellTd", 10.0, "Min Distance From Well TD", "", "", ""); + CAF_PDM_InitField(&m_maxFracturesPerWell, "MaxFracturesPerWell", 10, "Max Fractures Per Well", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_options, "Options", "Options", "", "", ""); + m_options.uiCapability()->setUiEditorTypeName(caf::PdmUiTableViewEditor::uiEditorTypeName()); + + m_options.push_back(new RicCreateMultipleFracturesOptionItemUi); + m_options.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); + m_options.uiCapability()->setCustomContextMenuEnabled(true); + + CAF_PDM_InitFieldNoDefault(&m_fractureCreationSummary, "FractureCreationSummary", "Summary", "", "", ""); + m_fractureCreationSummary.registerGetMethod(this, &RiuCreateMultipleFractionsUi::summaryText); + m_fractureCreationSummary.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); + m_fractureCreationSummary.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiuCreateMultipleFractionsUi::options() const +{ + return m_options.childObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::insertOptionItem(RicCreateMultipleFracturesOptionItemUi* insertBeforeThisObject, + RicCreateMultipleFracturesOptionItemUi* objectToInsert) +{ + size_t index = m_options.index(insertBeforeThisObject); + if (index < m_options.size()) + { + m_options.insert(index, objectToInsert); + } + else + { + m_options.push_back(objectToInsert); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::deleteOptionItem(RicCreateMultipleFracturesOptionItemUi* optionsItem) +{ + m_options.removeChildObject(optionsItem); + delete optionsItem; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RiuCreateMultipleFractionsUi::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) +{ + QList options; + + if (fieldNeedingOptions == &m_sourceCase) + { + RimTools::caseOptionItems(&options); + } + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::defineCustomContextMenu(const caf::PdmFieldHandle* fieldNeedingMenu, + QMenu* menu, + QWidget* fieldEditorWidget) +{ + caf::CmdFeatureMenuBuilder menuBuilder; + + menuBuilder << "RicNewOptionItemFeature"; + menuBuilder << "RicDeleteOptionItemFeature"; + + menuBuilder.appendToMenu(menu); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuCreateMultipleFractionsUi::summaryText() const +{ + std::vector locations = locationsForNewFractures(); + + std::set wellPathSet; + std::set fracTemplateSet; + + for (auto location : locations) + { + wellPathSet.insert(location.wellPath); + fracTemplateSet.insert(location.fractureTemplate); + } + + QString tableText; + tableText += "Fracture Template Count for selected wells\n\n"; + + { + QTextStream stream(&tableText); + RifEclipseDataTableFormatter formatter(stream); + formatter.setTableRowLineAppendText(""); + formatter.setTableRowPrependText(" "); + + std::vector header; + header.push_back(RifEclipseOutputTableColumn("Well Name")); + + for (auto fracTemplate : fracTemplateSet) + { + header.push_back(RifEclipseOutputTableColumn( + fracTemplate->name(), RifEclipseOutputTableDoubleFormatting(), RifEclipseOutputTableAlignment::RIGHT)); + } + + formatter.header(header); + + for (auto wellPath : wellPathSet) + { + formatter.add(wellPath->name()); + + for (auto fractureTemplate : fracTemplateSet) + { + size_t fractureTemplateCount = 0; + for (auto fracLocation : locations) + { + if (fractureTemplate == fracLocation.fractureTemplate && wellPath == fracLocation.wellPath) + { + fractureTemplateCount++; + } + } + + formatter.add(fractureTemplateCount); + } + + formatter.rowCompleted(); + } + + formatter.tableCompleted(); + } + + return tableText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) +{ + if (field == &m_fractureCreationSummary) + { + auto attr = dynamic_cast(attribute); + if (attr) + { + QFont font("Courier", 8); + + attr->font = font; + attr->heightHint = 100; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiuCreateMultipleFractionsUi::locationsForNewFractures() const +{ + std::vector items; + + RigMainGrid* mainGrid = nullptr; + + if (m_sourceCase && m_sourceCase->eclipseCaseData()) + { + mainGrid = m_sourceCase->eclipseCaseData()->mainGrid(); + } + + if (mainGrid) + { + std::vector selWells = caf::selectedObjectsByTypeStrict(); + + for (auto w : selWells) + { + auto wellPathGeometry = w->wellPathGeometry(); + if (wellPathGeometry) + { + auto mdOfWellPathTip = wellPathGeometry->measureDepths().back(); + + int fractureCountForWell = 0; + + for (const auto& option : m_options) + { + double currentMeasuredDepth = mdOfWellPathTip - m_minDistanceFromWellTd; + + bool continueSearch = true; + if (fractureCountForWell >= m_maxFracturesPerWell) + { + continueSearch = false; + } + + while (continueSearch) + { + auto locationInDomainCoords = wellPathGeometry->interpolatedPointAlongWellPath(currentMeasuredDepth); + + size_t reservoirGlobalCellIndex = mainGrid->findReservoirCellIndexFromPoint(locationInDomainCoords); + + if (reservoirGlobalCellIndex != cvf::UNDEFINED_SIZE_T) + { + size_t i; + size_t j; + size_t k; + mainGrid->ijkFromCellIndex(reservoirGlobalCellIndex, &i, &j, &k); + + if (option->isKLayerContained(static_cast(k))) + { + if (option->fractureTemplate()) + { + items.push_back(LocationForNewFracture(option->fractureTemplate(), w, currentMeasuredDepth)); + fractureCountForWell++; + } + } + } + + currentMeasuredDepth -= option->minimumSpacing(); + + if (currentMeasuredDepth < 0) + { + continueSearch = false; + } + + if (fractureCountForWell >= m_maxFracturesPerWell) + { + continueSearch = false; + } + } + } + } + } + } + + return items; +} diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.h b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.h new file mode 100644 index 0000000000..6e749fea87 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.h @@ -0,0 +1,86 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil 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 + +#include "RicCreateMultipleFracturesOptionItemUi.h" + +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmProxyValueField.h" + +class RimEclipseCase; +class RimWellPath; + +//================================================================================================== +/// +//================================================================================================== +class LocationForNewFracture +{ +public: + LocationForNewFracture(RimFractureTemplate* fractureTemplate, RimWellPath* wellPath, double measuredDepth) + : fractureTemplate(fractureTemplate) + , wellPath(wellPath) + , measuredDepth(measuredDepth) + { + } + + RimFractureTemplate* fractureTemplate; + RimWellPath* wellPath; + double measuredDepth; +}; + +//================================================================================================== +/// +//================================================================================================== +class RiuCreateMultipleFractionsUi : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RiuCreateMultipleFractionsUi(); + + std::vector options() const; + + void insertOptionItem(RicCreateMultipleFracturesOptionItemUi* insertBeforeThisObject, + RicCreateMultipleFracturesOptionItemUi* objectToInsert); + + void deleteOptionItem(RicCreateMultipleFracturesOptionItemUi* optionsItem); + + std::vector locationsForNewFractures() const; + +private: + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) override; + virtual void + defineCustomContextMenu(const caf::PdmFieldHandle* fieldNeedingMenu, QMenu* menu, QWidget* fieldEditorWidget) override; + virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) override; + + QString summaryText() const; + +private: + caf::PdmPtrField m_sourceCase; + caf::PdmField m_minDistanceFromWellTd; + caf::PdmField m_maxFracturesPerWell; + caf::PdmChildArrayField m_options; + + caf::PdmProxyValueField m_fractureCreationSummary; +}; diff --git a/ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.cpp b/ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.cpp new file mode 100644 index 0000000000..6b5ea27ed4 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.cpp @@ -0,0 +1,70 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil 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 "RicDeleteOptionItemFeature.h" + +#include "RicCreateMultipleFracturesOptionItemUi.h" +#include "RicCreateMultipleFracturesUi.h" + +#include "cafSelectionManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicDeleteOptionItemFeature, "RicDeleteOptionItemFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteOptionItemFeature::onActionTriggered(bool isChecked) +{ + std::vector optionItems; + caf::SelectionManager::instance()->objectsByType(&optionItems, caf::SelectionManager::CURRENT); + + if (!optionItems.empty()) + { + RiuCreateMultipleFractionsUi* multipleFractionUi = nullptr; + optionItems[0]->firstAncestorOrThisOfTypeAsserted(multipleFractionUi); + + for (auto optionItem : optionItems) + { + multipleFractionUi->deleteOptionItem(optionItem); + } + + multipleFractionUi->updateConnectedEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteOptionItemFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Delete Option Items"); + // actionToSetup->setIcon(QIcon(":/FractureTemplate16x16.png")); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicDeleteOptionItemFeature::isCommandEnabled() +{ + std::vector optionItems; + caf::SelectionManager::instance()->objectsByType(&optionItems, caf::SelectionManager::CURRENT); + + return !optionItems.empty(); +} diff --git a/ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.h b/ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.h new file mode 100644 index 0000000000..22e00bc583 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil 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 + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicDeleteOptionItemFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +private: + virtual bool isCommandEnabled() override; + virtual void setupActionLook(QAction* actionToSetup) override; + virtual void onActionTriggered(bool isChecked) override; +}; diff --git a/ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.cpp b/ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.cpp new file mode 100644 index 0000000000..3a1d94171e --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.cpp @@ -0,0 +1,78 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil 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 "RicNewOptionItemFeature.h" + +#include "RicCreateMultipleFracturesOptionItemUi.h" +#include "RicCreateMultipleFracturesUi.h" + +#include "cafPdmChildArrayField.h" +#include "cafSelectionManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicNewOptionItemFeature, "RicNewOptionItemFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewOptionItemFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewOptionItemFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New Option Item"); + // actionToSetup->setIcon(QIcon(":/Well.png")); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewOptionItemFeature::onActionTriggered(bool isChecked) +{ + RiuCreateMultipleFractionsUi* multipleFractionUi = nullptr; + RicCreateMultipleFracturesOptionItemUi* selectedOptionItem = nullptr; + + { + std::vector optionItems; + caf::SelectionManager::instance()->objectsByType(&optionItems, caf::SelectionManager::CURRENT); + if (!optionItems.empty()) + { + selectedOptionItem = optionItems.front(); + selectedOptionItem->firstAncestorOrThisOfTypeAsserted(multipleFractionUi); + } + } + + std::vector multipleFractions; + caf::SelectionManager::instance()->objectsByType(&multipleFractions, caf::SelectionManager::CURRENT); + if (!multipleFractions.empty()) + { + multipleFractionUi = multipleFractions[0]; + } + + if (multipleFractionUi) + { + multipleFractionUi->insertOptionItem(selectedOptionItem, new RicCreateMultipleFracturesOptionItemUi); + multipleFractionUi->updateConnectedEditors(); + } +} diff --git a/ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.h b/ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.h new file mode 100644 index 0000000000..8be38bfc40 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil 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 + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicNewOptionItemFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +private: + virtual bool isCommandEnabled() override; + virtual void setupActionLook(QAction* actionToSetup) override; + virtual void onActionTriggered(bool isChecked) override; +}; diff --git a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp index 5f3e3ba855..b356e2610e 100644 --- a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -299,6 +299,8 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "RicWellPathExportCompletionDataFeature"; menuBuilder.subMenuEnd(); + menuBuilder << "RicCreateMultipleFracturesFeature"; + menuBuilder << "Separator"; } @@ -727,6 +729,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() } } + menuBuilder << "RicCreateMultipleFracturesFeature"; menuBuilder << "RicWellPathImportCompletionsFileFeature"; menuBuilder << "RicFlyToObjectFeature"; menuBuilder << "RicExportCarfin"; diff --git a/ApplicationCode/ProjectDataModel/RimDialogData.cpp b/ApplicationCode/ProjectDataModel/RimDialogData.cpp index 79138b2a90..b1ace0f4f3 100644 --- a/ApplicationCode/ProjectDataModel/RimDialogData.cpp +++ b/ApplicationCode/ProjectDataModel/RimDialogData.cpp @@ -20,6 +20,7 @@ #include "ExportCommands/RicExportCarfinUi.h" #include "CompletionExportCommands/RicExportCompletionDataSettingsUi.h" +#include "FractureCommands/RicCreateMultipleFracturesUi.h" CAF_PDM_SOURCE_INIT(RimDialogData, "RimDialogData"); @@ -35,6 +36,9 @@ RimDialogData::RimDialogData() CAF_PDM_InitFieldNoDefault(&m_exportCompletionData, "ExportCompletionData", "Export Completion Data", "", "", ""); m_exportCompletionData = new RicExportCompletionDataSettingsUi(); + + CAF_PDM_InitFieldNoDefault(&m_multipleFractionsData, "MultipleFractionsData", "Multiple Fractures Data", "", "", ""); + m_multipleFractionsData = new RiuCreateMultipleFractionsUi(); } //-------------------------------------------------------------------------------------------------- @@ -70,3 +74,11 @@ RicExportCompletionDataSettingsUi* RimDialogData::exportCompletionData() const return m_exportCompletionData; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuCreateMultipleFractionsUi* RimDialogData::multipleFractionsData() const +{ + return m_multipleFractionsData; +} + diff --git a/ApplicationCode/ProjectDataModel/RimDialogData.h b/ApplicationCode/ProjectDataModel/RimDialogData.h index a03131c48d..39e194e941 100644 --- a/ApplicationCode/ProjectDataModel/RimDialogData.h +++ b/ApplicationCode/ProjectDataModel/RimDialogData.h @@ -1,47 +1,57 @@ ///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2017 Statoil 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #pragma once -#include "cafPdmObject.h" #include "cafPdmChildField.h" +#include "cafPdmObject.h" class RicExportCarfinUi; class RicExportCompletionDataSettingsUi; +class RiuCreateMultipleFractionsUi; //================================================================================================== -/// -/// +/// +/// This class is used as a container for UI specific data that is not part of the project tree view +/// Example of use is to store export settings for complex export dialogs or settings for advanced +/// creation of multiple objects +/// +/// The data in this object will be stored in the project file, as RimDialogData is a child object of +/// RimProject +/// //================================================================================================== class RimDialogData : public caf::PdmObject { - CAF_PDM_HEADER_INIT; + CAF_PDM_HEADER_INIT; public: RimDialogData(); - + RicExportCarfinUi* exportCarfin() const; QString exportCarfinDataAsString() const; void setExportCarfinDataFromString(const QString& data); RicExportCompletionDataSettingsUi* exportCompletionData() const; + RiuCreateMultipleFractionsUi* multipleFractionsData() const; + private: - caf::PdmChildField m_exportCarfin; - caf::PdmChildField m_exportCompletionData; + caf::PdmChildField m_exportCarfin; + caf::PdmChildField m_exportCompletionData; + caf::PdmChildField m_multipleFractionsData; };