From 4853957637dc6d5fd0d762a270e84c3448fb50e4 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 15 Mar 2018 21:25:54 +0100 Subject: [PATCH] #2544 Well CF Visualization: Add geometry generator and source info object rename remove unused move to separate file rename --- .../ModelVisualization/CMakeLists_files.cmake | 8 +- .../RivVirtualConnFactorPartMgr.cpp | 352 ------------------ ...vWellConnectionFactorGeometryGenerator.cpp | 222 +++++++++++ ...ivWellConnectionFactorGeometryGenerator.h} | 50 +-- .../RivWellConnectionFactorPartMgr.cpp | 193 ++++++++++ .../RivWellConnectionFactorPartMgr.h | 53 +++ .../RivWellConnectionSourceInfo.cpp | 50 +++ .../RivWellConnectionSourceInfo.h | 46 +++ .../ModelVisualization/RivWellPathPartMgr.cpp | 8 +- .../ModelVisualization/RivWellPathPartMgr.h | 6 +- 10 files changed, 596 insertions(+), 392 deletions(-) delete mode 100644 ApplicationCode/ModelVisualization/RivVirtualConnFactorPartMgr.cpp create mode 100644 ApplicationCode/ModelVisualization/RivWellConnectionFactorGeometryGenerator.cpp rename ApplicationCode/ModelVisualization/{RivVirtualConnFactorPartMgr.h => RivWellConnectionFactorGeometryGenerator.h} (56%) create mode 100644 ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.cpp create mode 100644 ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.h create mode 100644 ApplicationCode/ModelVisualization/RivWellConnectionSourceInfo.cpp create mode 100644 ApplicationCode/ModelVisualization/RivWellConnectionSourceInfo.h diff --git a/ApplicationCode/ModelVisualization/CMakeLists_files.cmake b/ApplicationCode/ModelVisualization/CMakeLists_files.cmake index 4801558943..d221f84380 100644 --- a/ApplicationCode/ModelVisualization/CMakeLists_files.cmake +++ b/ApplicationCode/ModelVisualization/CMakeLists_files.cmake @@ -39,7 +39,9 @@ ${CMAKE_CURRENT_LIST_DIR}/RivTensorResultPartMgr.h ${CMAKE_CURRENT_LIST_DIR}/RivWellFracturePartMgr.h ${CMAKE_CURRENT_LIST_DIR}/Riv3dWellLogPlanePartMgr.h ${CMAKE_CURRENT_LIST_DIR}/Riv3dWellLogCurveGeomertyGenerator.h -${CMAKE_CURRENT_LIST_DIR}/RivVirtualConnFactorPartMgr.h +${CMAKE_CURRENT_LIST_DIR}/RivWellConnectionFactorPartMgr.h +${CMAKE_CURRENT_LIST_DIR}/RivWellConnectionFactorGeometryGenerator.h +${CMAKE_CURRENT_LIST_DIR}/RivWellConnectionSourceInfo.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -77,7 +79,9 @@ ${CMAKE_CURRENT_LIST_DIR}/RivTensorResultPartMgr.cpp ${CMAKE_CURRENT_LIST_DIR}/RivWellFracturePartMgr.cpp ${CMAKE_CURRENT_LIST_DIR}/Riv3dWellLogPlanePartMgr.cpp ${CMAKE_CURRENT_LIST_DIR}/Riv3dWellLogCurveGeomertyGenerator.cpp -${CMAKE_CURRENT_LIST_DIR}/RivVirtualConnFactorPartMgr.cpp +${CMAKE_CURRENT_LIST_DIR}/RivWellConnectionFactorPartMgr.cpp +${CMAKE_CURRENT_LIST_DIR}/RivWellConnectionFactorGeometryGenerator.cpp +${CMAKE_CURRENT_LIST_DIR}/RivWellConnectionSourceInfo.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ModelVisualization/RivVirtualConnFactorPartMgr.cpp b/ApplicationCode/ModelVisualization/RivVirtualConnFactorPartMgr.cpp deleted file mode 100644 index 024879164c..0000000000 --- a/ApplicationCode/ModelVisualization/RivVirtualConnFactorPartMgr.cpp +++ /dev/null @@ -1,352 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// 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 "RivVirtualConnFactorPartMgr.h" - -#include "RiaApplication.h" -#include "RiaExtractionTools.h" - -#include "RigEclipseWellLogExtractor.h" -#include "RigMainGrid.h" -#include "RigVirtualPerforationTransmissibilities.h" -#include "RigWellLogExtractor.h" -#include "RigWellPath.h" - -#include "RimEclipseCase.h" -#include "RimEclipseView.h" -#include "RimLegendConfig.h" -#include "RimSimWellInViewCollection.h" -#include "RimVirtualPerforationResults.h" -#include "RimWellPath.h" - -#include "RiuViewer.h" - -#include "cafDisplayCoordTransform.h" -#include "cafEffectGenerator.h" -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cvfDrawableGeo.h" -#include "cvfGeometryBuilderFaceList.h" -#include "cvfGeometryBuilderTriangles.h" -#include "cvfGeometryUtils.h" -#include "cvfModelBasicList.h" -#include "cvfObject.h" -#include "cvfPart.h" -#include "cvfPrimitiveSetIndexedUInt.h" - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RivVirtualConnFactorPartMgr::RivVirtualConnFactorPartMgr(RimWellPath* well, - RimVirtualPerforationResults* virtualPerforationResult) - : m_rimWell(well) - , m_virtualPerforationResult(virtualPerforationResult) -{ -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RivVirtualConnFactorPartMgr::~RivVirtualConnFactorPartMgr() {} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivVirtualConnFactorPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex) -{ - RimEclipseView* eclView = nullptr; - m_virtualPerforationResult->firstAncestorOrThisOfTypeAsserted(eclView); - - auto coordTransform = eclView->displayCoordTransform(); - - RimEclipseCase* eclipseCase = nullptr; - m_virtualPerforationResult->firstAncestorOrThisOfTypeAsserted(eclipseCase); - - const RigMainGrid* mainGrid = eclipseCase->mainGrid(); - - const RigVirtualPerforationTransmissibilities* trans = eclipseCase->computeAndGetVirtualPerforationTransmissibilities(); - if (!trans) return; - - auto conn = trans->multipleCompletionsPerEclipseCell(m_rimWell, frameIndex); - - std::vector wellPathCellIntersections; - { - RigEclipseWellLogExtractor* extractor = RiaExtractionTools::wellLogExtractorEclipseCase(m_rimWell, eclipseCase); - if (extractor) - { - wellPathCellIntersections = extractor->cellIntersectionInfosAlongWellPath(); - } - } - - std::vector centerColorPairs; - for (const auto& cell : conn) - { - size_t gridIndex = cell.first.globalCellIndex(); - - const RigCell& rigCell = mainGrid->cell(gridIndex); - - cvf::Vec3d locationInDomainCoord = rigCell.center(); - cvf::Vec3d wellPathDirection = cvf::Vec3d::X_AXIS; - - if (!wellPathCellIntersections.empty()) - { - for (const auto& intersectionInfo : wellPathCellIntersections) - { - if (intersectionInfo.globCellIndex == cell.first.globalCellIndex()) - { - double startMD = intersectionInfo.startMD; - double endMD = intersectionInfo.endMD; - - double middleMD = (startMD + endMD) / 2.0; - - locationInDomainCoord = m_rimWell->wellPathGeometry()->interpolatedPointAlongWellPath(middleMD); - - cvf::Vec3d p1; - cvf::Vec3d p2; - m_rimWell->wellPathGeometry()->twoClosestPoints(locationInDomainCoord, &p1, &p2); - - wellPathDirection = (p2 - p1).getNormalized(); - - continue; - } - } - } - - cvf::Vec3d displayCoord = coordTransform->transformToDisplayCoord(locationInDomainCoord); - - double transmissibility = HUGE_VAL; - if (!cell.second.empty()) - { - transmissibility = cell.second.front().transmissibility(); - } - - centerColorPairs.push_back(CompletionVizData(displayCoord, wellPathDirection, transmissibility)); - } - - if (!centerColorPairs.empty()) - { - double radius = mainGrid->characteristicIJCellSize() * m_virtualPerforationResult->geometryScaleFactor(); - - auto scalarMapper = m_virtualPerforationResult->legendConfig()->scalarMapper(); - - bool disableLighting = eclView->isLightingDisabled(); - cvf::ref part = - RivVirtualConnFactorPartMgr::createPart(centerColorPairs, radius, scalarMapper, disableLighting); - - model->addPart(part.p()); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::ref RivVirtualConnFactorPartMgr::createPart(std::vector& vizDataItems, - double radius, - cvf::ScalarMapper* scalarMapper, - bool disableLighting) -{ - std::vector verticesForOneObject; - std::vector indicesForOneObject; - - RivVirtualConnFactorPartMgr::createStarGeometry(&verticesForOneObject, &indicesForOneObject, radius, radius * 0.3); - - cvf::ref vertices = new cvf::Vec3fArray; - cvf::ref indices = new cvf::UIntArray; - cvf::ref textureCoords = new cvf::Vec2fArray(); - - auto indexCount = vizDataItems.size() * indicesForOneObject.size(); - auto vertexCount = vizDataItems.size() * verticesForOneObject.size(); - indices->reserve(indexCount); - vertices->reserve(vertexCount); - textureCoords->reserve(vertexCount); - - textureCoords->setAll(cvf::Vec2f(0.5f, 1.0f)); - - for (const auto& item : vizDataItems) - { - auto rotMatrix = rotationMatrixBetweenVectors(cvf::Vec3d::Y_AXIS, item.m_direction); - - cvf::uint indexOffset = static_cast(vertices->size()); - - for (const auto& v : verticesForOneObject) - { - auto rotatedPoint = v.getTransformedPoint(rotMatrix); - - vertices->add(cvf::Vec3f(item.m_anchor) + rotatedPoint); - - if (item.m_connectionFactor == HUGE_VAL) - { - textureCoords->add(cvf::Vec2f(0.5f, 1.0f)); - } - else - { - textureCoords->add(scalarMapper->mapToTextureCoord(item.m_connectionFactor)); - } - } - - for (const auto& i : indicesForOneObject) - { - indices->add(i + indexOffset); - } - } - - cvf::ref drawable = new cvf::DrawableGeo(); - drawable->setVertexArray(vertices.p()); - - drawable->addPrimitiveSet(new cvf::PrimitiveSetIndexedUInt(cvf::PT_TRIANGLES, indices.p())); - drawable->computeNormals(); - - drawable->setTextureCoordArray(textureCoords.p()); - - cvf::ref part = new cvf::Part; - part->setDrawable(drawable.p()); - - caf::ScalarMapperEffectGenerator effGen(scalarMapper, caf::PO_1); - - effGen.disableLighting(disableLighting); - - cvf::ref eff = effGen.generateCachedEffect(); - part->setEffect(eff.p()); - - return part; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivVirtualConnFactorPartMgr::createStarGeometry(std::vector* vertices, - std::vector* indices, - double radius, - double thickness) -{ - auto p0 = cvf::Vec3f::Z_AXIS * radius; - auto p2 = cvf::Vec3f::X_AXIS * -radius; - auto p4 = -p0; - auto p6 = -p2; - - double innerFactor = 5.0; - - auto p1 = (p0 + p2) / innerFactor; - auto p3 = (p2 + p4) / innerFactor; - - auto p5 = -p1; - auto p7 = -p3; - - auto p8 = cvf::Vec3f::Y_AXIS * thickness; - auto p9 = -p8; - - vertices->push_back(p0); - vertices->push_back(p1); - vertices->push_back(p2); - vertices->push_back(p3); - vertices->push_back(p4); - vertices->push_back(p5); - vertices->push_back(p6); - vertices->push_back(p7); - vertices->push_back(p8); - vertices->push_back(p9); - - // Top - indices->push_back(0); - indices->push_back(1); - indices->push_back(8); - - indices->push_back(0); - indices->push_back(8); - indices->push_back(7); - - indices->push_back(0); - indices->push_back(9); - indices->push_back(1); - - indices->push_back(0); - indices->push_back(7); - indices->push_back(9); - - // Left - indices->push_back(2); - indices->push_back(3); - indices->push_back(8); - - indices->push_back(2); - indices->push_back(8); - indices->push_back(1); - - indices->push_back(2); - indices->push_back(9); - indices->push_back(3); - - indices->push_back(2); - indices->push_back(1); - indices->push_back(9); - - // Bottom - indices->push_back(4); - indices->push_back(5); - indices->push_back(8); - - indices->push_back(4); - indices->push_back(8); - indices->push_back(3); - - indices->push_back(4); - indices->push_back(9); - indices->push_back(5); - - indices->push_back(4); - indices->push_back(3); - indices->push_back(9); - - // Right - indices->push_back(6); - indices->push_back(7); - indices->push_back(8); - - indices->push_back(6); - indices->push_back(8); - indices->push_back(5); - - indices->push_back(6); - indices->push_back(9); - indices->push_back(7); - - indices->push_back(6); - indices->push_back(5); - indices->push_back(9); -} - -//-------------------------------------------------------------------------------------------------- -/// Taken from OverlayNavigationCube::computeNewUpVector -/// Consider move to geometry util class -//-------------------------------------------------------------------------------------------------- -cvf::Mat4f RivVirtualConnFactorPartMgr::rotationMatrixBetweenVectors(const cvf::Vec3d& v1, const cvf::Vec3d& v2) -{ - using namespace cvf; - - Vec3d rotAxis = v1 ^ v2; - rotAxis.normalize(); - - // Guard acos against out-of-domain input - const double dotProduct = Math::clamp(v1 * v2, -1.0, 1.0); - const double angle = Math::acos(dotProduct); - Mat4d rotMat = Mat4d::fromRotation(rotAxis, angle); - - Mat4f myMat(rotMat); - - return myMat; -} diff --git a/ApplicationCode/ModelVisualization/RivWellConnectionFactorGeometryGenerator.cpp b/ApplicationCode/ModelVisualization/RivWellConnectionFactorGeometryGenerator.cpp new file mode 100644 index 0000000000..cf65996a71 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivWellConnectionFactorGeometryGenerator.cpp @@ -0,0 +1,222 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RivWellConnectionFactorGeometryGenerator.h" + +#include "cvfArray.h" +#include "cvfDrawableGeo.h" +#include "cvfPrimitiveSetIndexedUInt.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivWellConnectionFactorGeometryGenerator::createStarGeometry(std::vector* vertices, + std::vector* indices, + float radius, + float thickness) +{ + auto p0 = cvf::Vec3f::Z_AXIS * radius; + auto p2 = cvf::Vec3f::X_AXIS * -radius; + auto p4 = -p0; + auto p6 = -p2; + + float innerFactor = 5.0f; + + auto p1 = (p0 + p2) / innerFactor; + auto p3 = (p2 + p4) / innerFactor; + + auto p5 = -p1; + auto p7 = -p3; + + auto p8 = cvf::Vec3f::Y_AXIS * thickness; + auto p9 = -p8; + + vertices->push_back(p0); + vertices->push_back(p1); + vertices->push_back(p2); + vertices->push_back(p3); + vertices->push_back(p4); + vertices->push_back(p5); + vertices->push_back(p6); + vertices->push_back(p7); + vertices->push_back(p8); + vertices->push_back(p9); + + // Top + indices->push_back(0); + indices->push_back(1); + indices->push_back(8); + + indices->push_back(0); + indices->push_back(8); + indices->push_back(7); + + indices->push_back(0); + indices->push_back(9); + indices->push_back(1); + + indices->push_back(0); + indices->push_back(7); + indices->push_back(9); + + // Left + indices->push_back(2); + indices->push_back(3); + indices->push_back(8); + + indices->push_back(2); + indices->push_back(8); + indices->push_back(1); + + indices->push_back(2); + indices->push_back(9); + indices->push_back(3); + + indices->push_back(2); + indices->push_back(1); + indices->push_back(9); + + // Bottom + indices->push_back(4); + indices->push_back(5); + indices->push_back(8); + + indices->push_back(4); + indices->push_back(8); + indices->push_back(3); + + indices->push_back(4); + indices->push_back(9); + indices->push_back(5); + + indices->push_back(4); + indices->push_back(3); + indices->push_back(9); + + // Right + indices->push_back(6); + indices->push_back(7); + indices->push_back(8); + + indices->push_back(6); + indices->push_back(8); + indices->push_back(5); + + indices->push_back(6); + indices->push_back(9); + indices->push_back(7); + + indices->push_back(6); + indices->push_back(5); + indices->push_back(9); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivWellConnectionFactorGeometryGenerator::RivWellConnectionFactorGeometryGenerator( + std::vector& centerColorPairs, + float radius) + : m_centerColorPairs(centerColorPairs) + , m_radius(radius) + , m_trianglesPerConnection(0) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivWellConnectionFactorGeometryGenerator::~RivWellConnectionFactorGeometryGenerator() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RivWellConnectionFactorGeometryGenerator::createPipeSurface() +{ + std::vector verticesForOneObject; + std::vector indicesForOneObject; + + RivWellConnectionFactorGeometryGenerator::createStarGeometry( + &verticesForOneObject, &indicesForOneObject, m_radius, m_radius * 0.3f); + + cvf::ref vertices = new cvf::Vec3fArray; + cvf::ref indices = new cvf::UIntArray; + + auto indexCount = m_centerColorPairs.size() * indicesForOneObject.size(); + auto vertexCount = m_centerColorPairs.size() * verticesForOneObject.size(); + indices->reserve(indexCount); + vertices->reserve(vertexCount); + + for (const auto& item : m_centerColorPairs) + { + auto rotMatrix = rotationMatrixBetweenVectors(cvf::Vec3d::Y_AXIS, item.m_direction); + + cvf::uint indexOffset = static_cast(vertices->size()); + + for (const auto& v : verticesForOneObject) + { + auto rotatedPoint = v.getTransformedPoint(rotMatrix); + + vertices->add(cvf::Vec3f(item.m_anchor) + rotatedPoint); + } + + for (const auto& i : indicesForOneObject) + { + indices->add(i + indexOffset); + } + } + + cvf::ref drawable = new cvf::DrawableGeo(); + drawable->setVertexArray(vertices.p()); + + drawable->addPrimitiveSet(new cvf::PrimitiveSetIndexedUInt(cvf::PT_TRIANGLES, indices.p())); + drawable->computeNormals(); + + return drawable; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RivWellConnectionFactorGeometryGenerator::globalCellIndexFromTriangleIndex(cvf::uint triangleIndex) const +{ + size_t connectionIndex = triangleIndex / m_trianglesPerConnection; + + return m_centerColorPairs[connectionIndex].m_globalCellIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// Taken from OverlayNavigationCube::computeNewUpVector +/// Consider move to geometry util class +//-------------------------------------------------------------------------------------------------- +cvf::Mat4f RivWellConnectionFactorGeometryGenerator::rotationMatrixBetweenVectors(const cvf::Vec3d& v1, const cvf::Vec3d& v2) +{ + using namespace cvf; + + Vec3d rotAxis = v1 ^ v2; + rotAxis.normalize(); + + // Guard acos against out-of-domain input + const double dotProduct = Math::clamp(v1 * v2, -1.0, 1.0); + const double angle = Math::acos(dotProduct); + Mat4d rotMat = Mat4d::fromRotation(rotAxis, angle); + + Mat4f myMat(rotMat); + + return myMat; +} diff --git a/ApplicationCode/ModelVisualization/RivVirtualConnFactorPartMgr.h b/ApplicationCode/ModelVisualization/RivWellConnectionFactorGeometryGenerator.h similarity index 56% rename from ApplicationCode/ModelVisualization/RivVirtualConnFactorPartMgr.h rename to ApplicationCode/ModelVisualization/RivWellConnectionFactorGeometryGenerator.h index 725db29aa0..504a9b81b4 100644 --- a/ApplicationCode/ModelVisualization/RivVirtualConnFactorPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellConnectionFactorGeometryGenerator.h @@ -19,68 +19,56 @@ #pragma once #include "cvfBase.h" +#include "cvfMatrix4.h" #include "cvfObject.h" #include "cvfVector3.h" -#include "cvfMatrix4.h" - -#include "cafPdmPointer.h" #include namespace cvf { -class Part; -class ModelBasicList; -class ScalarMapper; +class DrawableGeo; } // namespace cvf -class RimWellPath; -class RimVirtualPerforationResults; - -namespace caf -{ -class DisplayCoordTransform; -} - +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- struct CompletionVizData { - CompletionVizData(cvf::Vec3d anchor, cvf::Vec3d direction, double connectionFactor) + CompletionVizData(const cvf::Vec3d& anchor, const cvf::Vec3d& direction, double connectionFactor, size_t globalCellIndex) : m_anchor(anchor) , m_direction(direction) , m_connectionFactor(connectionFactor) + , m_globalCellIndex(globalCellIndex) { } cvf::Vec3d m_anchor; cvf::Vec3d m_direction; double m_connectionFactor; + size_t m_globalCellIndex; }; - //-------------------------------------------------------------------------------------------------- /// -/// Based on RivWellSpheresPartMgr -/// //-------------------------------------------------------------------------------------------------- -class RivVirtualConnFactorPartMgr : public cvf::Object +class RivWellConnectionFactorGeometryGenerator : public cvf::Object { public: - RivVirtualConnFactorPartMgr(RimWellPath* well, RimVirtualPerforationResults* virtualPerforationResult); - ~RivVirtualConnFactorPartMgr(); + RivWellConnectionFactorGeometryGenerator(std::vector& centerColorPairs, float radius); + ~RivWellConnectionFactorGeometryGenerator(); - void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex); + cvf::ref createPipeSurface(); + + size_t globalCellIndexFromTriangleIndex(cvf::uint triangleIndex) const; private: - static cvf::ref createPart(std::vector& centerColorPairs, - double radius, - cvf::ScalarMapper* scalarMapper, - bool disableLighting); - - static void createStarGeometry(std::vector* vertices, std::vector* indices, double radius, double thickness); - static cvf::Mat4f rotationMatrixBetweenVectors(const cvf::Vec3d& v1, const cvf::Vec3d& v2); + static void + createStarGeometry(std::vector* vertices, std::vector* indices, float radius, float thickness); private: - caf::PdmPointer m_rimWell; - caf::PdmPointer m_virtualPerforationResult; + std::vector m_centerColorPairs; + float m_radius; + size_t m_trianglesPerConnection; }; diff --git a/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.cpp new file mode 100644 index 0000000000..cc633613d3 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.cpp @@ -0,0 +1,193 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RivWellConnectionFactorPartMgr.h" + +#include "RiaApplication.h" +#include "RiaExtractionTools.h" + +#include "RigEclipseWellLogExtractor.h" +#include "RigMainGrid.h" +#include "RigVirtualPerforationTransmissibilities.h" +#include "RigWellLogExtractor.h" +#include "RigWellPath.h" + +#include "RimEclipseCase.h" +#include "RimEclipseView.h" +#include "RimLegendConfig.h" +#include "RimSimWellInViewCollection.h" +#include "RimVirtualPerforationResults.h" +#include "RimWellPath.h" + +#include "RiuViewer.h" + +#include "RivWellConnectionFactorGeometryGenerator.h" +#include "RivWellConnectionSourceInfo.h" + +#include "cafDisplayCoordTransform.h" +#include "cafEffectGenerator.h" +#include "cvfDrawableGeo.h" +#include "cvfModelBasicList.h" +#include "cvfPart.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivWellConnectionFactorPartMgr::RivWellConnectionFactorPartMgr(RimWellPath* well, + RimVirtualPerforationResults* virtualPerforationResult) + : m_rimWell(well) + , m_virtualPerforationResult(virtualPerforationResult) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivWellConnectionFactorPartMgr::~RivWellConnectionFactorPartMgr() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivWellConnectionFactorPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex) +{ + m_geometryGenerator = nullptr; + + RimEclipseView* eclView = nullptr; + m_virtualPerforationResult->firstAncestorOrThisOfTypeAsserted(eclView); + + auto coordTransform = eclView->displayCoordTransform(); + + RimEclipseCase* eclipseCase = nullptr; + m_virtualPerforationResult->firstAncestorOrThisOfTypeAsserted(eclipseCase); + + const RigMainGrid* mainGrid = eclipseCase->mainGrid(); + + const RigVirtualPerforationTransmissibilities* trans = eclipseCase->computeAndGetVirtualPerforationTransmissibilities(); + if (!trans) return; + + auto conn = trans->multipleCompletionsPerEclipseCell(m_rimWell, frameIndex); + + std::vector wellPathCellIntersections; + { + RigEclipseWellLogExtractor* extractor = RiaExtractionTools::wellLogExtractorEclipseCase(m_rimWell, eclipseCase); + if (extractor) + { + wellPathCellIntersections = extractor->cellIntersectionInfosAlongWellPath(); + } + } + + std::vector mapFromConnectionIndexToGlobalCellIndex; + + std::vector centerColorPairs; + for (const auto& cell : conn) + { + size_t gridIndex = cell.first.globalCellIndex(); + + const RigCell& rigCell = mainGrid->cell(gridIndex); + + cvf::Vec3d locationInDomainCoord = rigCell.center(); + cvf::Vec3d wellPathDirection = cvf::Vec3d::X_AXIS; + + if (!wellPathCellIntersections.empty()) + { + for (const auto& intersectionInfo : wellPathCellIntersections) + { + if (intersectionInfo.globCellIndex == cell.first.globalCellIndex()) + { + double startMD = intersectionInfo.startMD; + double endMD = intersectionInfo.endMD; + + double middleMD = (startMD + endMD) / 2.0; + + locationInDomainCoord = m_rimWell->wellPathGeometry()->interpolatedPointAlongWellPath(middleMD); + + cvf::Vec3d p1; + cvf::Vec3d p2; + m_rimWell->wellPathGeometry()->twoClosestPoints(locationInDomainCoord, &p1, &p2); + + wellPathDirection = (p2 - p1).getNormalized(); + + continue; + } + } + } + + cvf::Vec3d displayCoord = coordTransform->transformToDisplayCoord(locationInDomainCoord); + + double transmissibility = HUGE_VAL; + if (!cell.second.empty()) + { + transmissibility = cell.second.front().transmissibility(); + } + + centerColorPairs.push_back( + CompletionVizData(displayCoord, wellPathDirection, transmissibility, cell.first.globalCellIndex())); + mapFromConnectionIndexToGlobalCellIndex.push_back(cell.first.globalCellIndex()); + } + + if (!centerColorPairs.empty()) + { + double radius = mainGrid->characteristicIJCellSize() * m_virtualPerforationResult->geometryScaleFactor(); + + m_geometryGenerator = new RivWellConnectionFactorGeometryGenerator(centerColorPairs, radius); + auto drawable = m_geometryGenerator->createPipeSurface(); + + cvf::ref part = new cvf::Part; + part->setDrawable(drawable.p()); + + auto scalarMapper = m_virtualPerforationResult->legendConfig()->scalarMapper(); + + // Compute texture coords + cvf::ref textureCoords = new cvf::Vec2fArray(); + { + textureCoords->reserve(drawable->vertexArray()->size()); + size_t verticesPerItem = drawable->vertexArray()->size() / centerColorPairs.size(); + + textureCoords->setAll(cvf::Vec2f(0.5f, 1.0f)); + + for (const auto& item : centerColorPairs) + { + cvf::Vec2f textureCoord = cvf::Vec2f(0.5f, 1.0f); + if (item.m_connectionFactor != HUGE_VAL) + { + textureCoord = scalarMapper->mapToTextureCoord(item.m_connectionFactor); + } + + for (size_t i = 0; i < verticesPerItem; i++) + { + textureCoords->add(textureCoord); + } + } + } + + drawable->setTextureCoordArray(textureCoords.p()); + + caf::ScalarMapperEffectGenerator effGen(scalarMapper, caf::PO_1); + + bool disableLighting = eclView->isLightingDisabled(); + effGen.disableLighting(disableLighting); + + cvf::ref eff = effGen.generateCachedEffect(); + part->setEffect(eff.p()); + + cvf::ref sourceInfo = new RivWellConnectionSourceInfo(m_rimWell, m_geometryGenerator.p()); + part->setSourceInfo(sourceInfo.p()); + + model->addPart(part.p()); + } +} diff --git a/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.h b/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.h new file mode 100644 index 0000000000..ac1b5e0f11 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.h @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "cvfBase.h" +#include "cvfObject.h" + +#include "cafPdmPointer.h" + +#include + +namespace cvf +{ +class ModelBasicList; +} // namespace cvf + +class RimWellPath; +class RimVirtualPerforationResults; +class RivWellConnectionFactorGeometryGenerator; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class RivWellConnectionFactorPartMgr : public cvf::Object +{ +public: + RivWellConnectionFactorPartMgr(RimWellPath* well, RimVirtualPerforationResults* virtualPerforationResult); + ~RivWellConnectionFactorPartMgr(); + + void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex); + +private: + caf::PdmPointer m_rimWell; + caf::PdmPointer m_virtualPerforationResult; + + cvf::ref m_geometryGenerator; +}; diff --git a/ApplicationCode/ModelVisualization/RivWellConnectionSourceInfo.cpp b/ApplicationCode/ModelVisualization/RivWellConnectionSourceInfo.cpp new file mode 100644 index 0000000000..5dbc092435 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivWellConnectionSourceInfo.cpp @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RivWellConnectionSourceInfo.h" + +#include "RimWellPath.h" +#include "RivWellConnectionFactorGeometryGenerator.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivWellConnectionSourceInfo::RivWellConnectionSourceInfo(RimWellPath* wellPath, + RivWellConnectionFactorGeometryGenerator* geometryGenerator) + : m_wellPath(wellPath) + , m_geometryGenerator(geometryGenerator) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPath* RivWellConnectionSourceInfo::wellPath() const +{ + return m_wellPath; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RivWellConnectionSourceInfo::globalCellIndexFromTriangleIndex(cvf::uint triangleIndex) const +{ + if (m_geometryGenerator.isNull()) return 0; + + return m_geometryGenerator->globalCellIndexFromTriangleIndex(triangleIndex); +} diff --git a/ApplicationCode/ModelVisualization/RivWellConnectionSourceInfo.h b/ApplicationCode/ModelVisualization/RivWellConnectionSourceInfo.h new file mode 100644 index 0000000000..c02205143d --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivWellConnectionSourceInfo.h @@ -0,0 +1,46 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "cafPdmPointer.h" + +#include "cvfBase.h" +#include "cvfObject.h" + +#include + +class RimWellPath; +class RivWellConnectionFactorGeometryGenerator; + +//================================================================================================== +/// +//================================================================================================== +class RivWellConnectionSourceInfo : public cvf::Object +{ +public: + explicit RivWellConnectionSourceInfo(RimWellPath* wellPath, RivWellConnectionFactorGeometryGenerator* geometryGenerator); + + RimWellPath* wellPath() const; + + size_t globalCellIndexFromTriangleIndex(cvf::uint triangleIndex) const; + +private: + caf::PdmPointer m_wellPath; + cvf::ref m_geometryGenerator; +}; diff --git a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp index 8bda6e44cf..c5679810cb 100644 --- a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp @@ -47,6 +47,7 @@ #include "RivObjectSourceInfo.h" #include "RivPartPriority.h" #include "RivPipeGeometryGenerator.h" +#include "RivWellConnectionFactorPartMgr.h" #include "RivWellFracturePartMgr.h" #include "RivWellPathPartMgr.h" #include "RivWellPathSourceInfo.h" @@ -63,7 +64,6 @@ #include "cvfScalarMapperDiscreteLinear.h" #include "cvfTransform.h" #include "cvfqtUtils.h" -#include "RivVirtualConnFactorPartMgr.h" //-------------------------------------------------------------------------------------------------- @@ -178,7 +178,7 @@ void RivWellPathPartMgr::appendPerforationsToModel(cvf::ModelBasicList* model, size_t timeStepIndex = m_rimView->currentTimeStep(); std::vector timeStamps = eclipseCase->timeStepDates(); - if (timeStepIndex < static_cast(timeStamps.size())) + if (timeStepIndex < timeStamps.size()) { currentTimeStamp = timeStamps[timeStepIndex]; } @@ -238,11 +238,11 @@ void RivWellPathPartMgr::appendVirtualTransmissibilitiesToModel(cvf::ModelBasicL const RigVirtualPerforationTransmissibilities* trans = eclipseCase->computeAndGetVirtualPerforationTransmissibilities(); if (trans) { - m_virtualConnectionFactorPartMgr = new RivVirtualConnFactorPartMgr(m_rimWellPath, eclView->virtualPerforationResult()); + m_wellConnectionFactorPartMgr = new RivWellConnectionFactorPartMgr(m_rimWellPath, eclView->virtualPerforationResult()); size_t timeStepIndex = m_rimView->currentTimeStep(); - m_virtualConnectionFactorPartMgr->appendDynamicGeometryPartsToModel(model, timeStepIndex); + m_wellConnectionFactorPartMgr->appendDynamicGeometryPartsToModel(model, timeStepIndex); } } diff --git a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.h b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.h index afd6aea4ea..cc8d9433ec 100644 --- a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.h @@ -46,7 +46,7 @@ class RivFishbonesSubsPartMgr; class RimWellPathCollection; class Rim3dView; class Riv3dWellLogPlanePartMgr; -class RivVirtualConnFactorPartMgr; +class RivWellConnectionFactorPartMgr; class QDateTime; @@ -110,6 +110,6 @@ private: cvf::ref m_centerLineDrawable; cvf::ref m_wellLabelPart; - cvf::ref m_3dWellLogCurvePartMgr; - cvf::ref m_virtualConnectionFactorPartMgr; + cvf::ref m_3dWellLogCurvePartMgr; + cvf::ref m_wellConnectionFactorPartMgr; };