///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2016- 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 "RivWellSpheresPartMgr.h" #include "RiaGuiApplication.h" #include "RigMainGrid.h" #include "Well/RigSimWellData.h" #include "Well/RigWellResultFrame.h" #include "Well/RigWellResultPoint.h" #include "RimEclipseCase.h" #include "RimEclipseView.h" #include "RimSimWellInView.h" #include "RimSimWellInViewCollection.h" #include "RiuViewer.h" #include "cafDisplayCoordTransform.h" #include "cafEffectGenerator.h" #include "cafPdmFieldCvfColor.h" #include "cafPdmFieldCvfMat4d.h" #include "cvfDrawableGeo.h" #include "cvfDrawableVectors.h" #include "cvfGeometryBuilderFaceList.h" #include "cvfGeometryBuilderTriangles.h" #include "cvfGeometryUtils.h" #include "cvfModelBasicList.h" #include "cvfObject.h" #include "cvfOpenGLResourceManager.h" #include "cvfPart.h" #include "cvfShaderProgram.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RivWellSpheresPartMgr::RivWellSpheresPartMgr( RimEclipseView* reservoirView, RimSimWellInView* well ) { m_rimReservoirView = reservoirView; m_rimWell = well; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RivWellSpheresPartMgr::~RivWellSpheresPartMgr() { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivWellSpheresPartMgr::appendDynamicGeometryPartsToModel( cvf::ModelBasicList* model, size_t frameIndex ) { if ( m_rimReservoirView.isNull() ) return; if ( !m_rimReservoirView->eclipseCase() ) return; if ( !m_rimReservoirView->eclipseCase()->eclipseCaseData() ) return; const RigMainGrid* mainGrid = m_rimReservoirView->mainGrid(); CVF_ASSERT( mainGrid ); RigSimWellData* rigWellResult = m_rimWell->simWellData(); if ( !rigWellResult ) return; if ( !rigWellResult->hasWellResult( frameIndex ) ) return; const RigWellResultFrame* wellResultFrame = rigWellResult->wellResultFrame( frameIndex ); std::vector> centerColorPairs; for ( const RigWellResultBranch& wellResultBranch : wellResultFrame->wellResultBranches() ) { for ( const RigWellResultPoint& wellResultPoint : wellResultBranch.branchResultPoints() ) { size_t gridIndex = wellResultPoint.gridIndex(); if ( gridIndex >= mainGrid->gridCount() ) continue; const RigGridBase* rigGrid = mainGrid->gridByIndex( gridIndex ); size_t gridCellIndex = wellResultPoint.cellIndex(); if ( gridCellIndex >= rigGrid->cellCount() ) continue; const RigCell& rigCell = rigGrid->cell( gridCellIndex ); cvf::Vec3d center = rigCell.center(); cvf::ref transForm = m_rimReservoirView->displayCoordTransform(); cvf::Vec3d displayCoord = transForm->transformToDisplayCoord( center ); cvf::Color3f color = wellCellColor( wellResultFrame, wellResultPoint ); centerColorPairs.push_back( std::make_pair( cvf::Vec3f( displayCoord ), color ) ); } } if ( !centerColorPairs.empty() ) { cvf::ref part = createPart( centerColorPairs, wellResultFrame->isOpen() ); model->addPart( part.p() ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::ref RivWellSpheresPartMgr::createPart( std::vector>& centerColorPairs, bool isWellOpen ) { cvf::ref vertices = new cvf::Vec3fArray; cvf::ref vecRes = new cvf::Vec3fArray; cvf::ref colors = new cvf::Color3fArray; size_t numVecs = centerColorPairs.size(); vertices->reserve( numVecs ); vecRes->reserve( numVecs ); colors->reserve( numVecs ); for ( auto centerColorPair : centerColorPairs ) { vertices->add( centerColorPair.first ); vecRes->add( cvf::Vec3f::X_AXIS ); colors->add( centerColorPair.second ); } cvf::ref vectorDrawable; if ( RiaGuiApplication::instance()->useShaders() ) { // NOTE: Drawable vectors must be rendered using shaders when the rest of the application is rendered using // shaders Drawing vectors using fixed function when rest of the application uses shaders causes visual // artifacts vectorDrawable = new cvf::DrawableVectors( "u_transformationMatrix", "u_color" ); } else { vectorDrawable = new cvf::DrawableVectors(); } vectorDrawable->setVectors( vertices.p(), vecRes.p() ); vectorDrawable->setColors( colors.p() ); cvf::GeometryBuilderTriangles builder; double characteristicCellSize = m_rimReservoirView->mainGrid()->characteristicIJCellSize(); double cellRadius = m_rimReservoirView->wellCollection()->spheresScaleFactor() * characteristicCellSize; if ( isWellOpen ) { // Increase radius to make sure open connection are slightly larger than closed connections cellRadius = 1.1 * cellRadius; } cvf::GeometryUtils::createSphere( cellRadius, 15, 15, &builder ); vectorDrawable->setGlyph( builder.trianglesUShort().p(), builder.vertices().p() ); cvf::ref part = new cvf::Part; part->setName( "RivWellSpheresPartMgr" ); part->setDrawable( vectorDrawable.p() ); cvf::ref eff = new cvf::Effect; if ( RiaGuiApplication::instance()->useShaders() ) { if ( m_rimReservoirView->viewer() ) { cvf::ref oglContext = m_rimReservoirView->viewer()->cvfOpenGLContext(); if ( oglContext.notNull() ) { cvf::OpenGLResourceManager* resourceManager = oglContext->resourceManager(); cvf::ref vectorProgram = resourceManager->getLinkedVectorDrawerShaderProgram( oglContext.p() ); eff->setShaderProgram( vectorProgram.p() ); } } } part->setEffect( eff.p() ); return part; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::Color3f RivWellSpheresPartMgr::wellCellColor( const RigWellResultFrame* wellResultFrame, const RigWellResultPoint& wellResultPoint ) { // Colours should be synchronized with RivWellPipesPartMgr::updatePipeResultColor cvf::Color3f cellColor( cvf::Color3f::GRAY ); RimSimWellInViewCollection* wellColl = nullptr; if ( m_rimWell ) { wellColl = m_rimWell->firstAncestorOrThisOfType(); } if ( wellColl ) { if ( wellResultPoint.isOpen() ) { switch ( wellResultFrame->productionType() ) { case RiaDefines::WellProductionType::PRODUCER: cellColor = cvf::Color3f::GREEN; break; case RiaDefines::WellProductionType::OIL_INJECTOR: cellColor = cvf::Color3f::RED; break; case RiaDefines::WellProductionType::GAS_INJECTOR: cellColor = cvf::Color3f::RED; break; case RiaDefines::WellProductionType::WATER_INJECTOR: cellColor = cvf::Color3f::BLUE; break; } } } return cellColor; }