Пример #1
0
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanElementColorSurfacePart(const RimEclipseView& activeView)
{
    CVF_ASSERT(m_rimFracture);
    RimStimPlanFractureTemplate* stimPlanFracTemplate =
        dynamic_cast<RimStimPlanFractureTemplate*>(m_rimFracture->fractureTemplate());
    CVF_ASSERT(stimPlanFracTemplate);

    if (!stimPlanFracTemplate->fractureGrid()) return nullptr;

    auto displayCoordTransform = activeView.displayCoordTransform();
    if (displayCoordTransform.isNull()) return nullptr;

    std::vector<cvf::Vec3f>   stimPlanMeshVertices;
    cvf::ref<cvf::Vec2fArray> textureCoords = new cvf::Vec2fArray;
    const cvf::ScalarMapper*  scalarMapper  = nullptr;

    {
        std::vector<RigFractureCell> stimPlanCells = stimPlanFracTemplate->fractureGrid()->fractureCells();

        RimRegularLegendConfig* legendConfig = nullptr;
        if (activeView.fractureColors() && activeView.fractureColors()->isChecked() &&
            activeView.fractureColors()->activeLegend())
        {
            legendConfig = activeView.fractureColors()->activeLegend();

            scalarMapper = legendConfig->scalarMapper();

            QString resultNameFromColors = activeView.fractureColors()->uiResultName();
            QString resultUnitFromColors = activeView.fractureColors()->unit();

            std::vector<double> prCellResults = stimPlanFracTemplate->fractureGridResults(
                resultNameFromColors, resultUnitFromColors, stimPlanFracTemplate->activeTimeStepIndex());

            textureCoords->reserve(prCellResults.size() * 4);

            for (size_t cIdx = 0; cIdx < stimPlanCells.size(); ++cIdx)
            {
                if (prCellResults[cIdx] > 1e-7)
                {
                    const RigFractureCell&  stimPlanCell        = stimPlanCells[cIdx];
                    std::vector<cvf::Vec3d> stimPlanCellPolygon = stimPlanCell.getPolygon();
                    for (const cvf::Vec3d& cellCorner : stimPlanCellPolygon)
                    {
                        stimPlanMeshVertices.push_back(static_cast<cvf::Vec3f>(cellCorner));
                        textureCoords->add(scalarMapper->mapToTextureCoord(prCellResults[cIdx]));
                    }
                }
            }

            textureCoords->squeeze();
        }
        else
        {
            for (const auto& stimPlanCell : stimPlanCells)
            {
                for (const auto& cellCorner : stimPlanCell.getPolygon())
                {
                    stimPlanMeshVertices.push_back(static_cast<cvf::Vec3f>(cellCorner));
                }
            }
        }
    }

    if (stimPlanMeshVertices.empty())
    {
        return nullptr;
    }

    cvf::Mat4d              fractureXf = m_rimFracture->transformMatrix();
    std::vector<cvf::Vec3f> nodeDisplayCoords =
        transformToFractureDisplayCoords(stimPlanMeshVertices, fractureXf, *displayCoordTransform);

    std::vector<cvf::uint> triIndicesToInclude;

    size_t cellCount = stimPlanMeshVertices.size() / 4;
    for (cvf::uint i = 0; i < cellCount; i++)
    {
        triIndicesToInclude.push_back(i * 4 + 0);
        triIndicesToInclude.push_back(i * 4 + 1);
        triIndicesToInclude.push_back(i * 4 + 2);

        triIndicesToInclude.push_back(i * 4 + 0);
        triIndicesToInclude.push_back(i * 4 + 2);
        triIndicesToInclude.push_back(i * 4 + 3);
    }

    // Show selected result on the surface geometry and filter out triangles that have result values near 0
    if (scalarMapper)
    {
        if (triIndicesToInclude.empty())
        {
            return nullptr;
        }

        cvf::ref<cvf::DrawableGeo> geo = buildDrawableGeoFromTriangles(triIndicesToInclude, nodeDisplayCoords);
        geo->setTextureCoordArray(textureCoords.p());

        cvf::ref<cvf::Part> surfacePart =
            createScalarMapperPart(geo.p(), scalarMapper, m_rimFracture, activeView.isLightingDisabled());

        return surfacePart;
    }
    else
    {
        // No result is mapped, show the entire StimPlan surface with default color

        return createSingleColorSurfacePart(triIndicesToInclude, nodeDisplayCoords, activeView.fractureColors()->defaultColor());
    }
}
Пример #2
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCellColors* cellResultColors)
{
    CVF_ASSERT(cellResultColors);

    updateNNCColors(cellResultColors);

    RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultColors->porosityModel());
    RimEclipseView* eclipseView = cellResultColors->reservoirView();
    RigCaseData* eclipseCase = eclipseView->eclipseCase()->reservoirData();

    // Faults
    if (m_nativeFaultFaces.notNull())
    {
        if (cellResultColors->isTernarySaturationSelected())
        {
            RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(),
                timeStepIndex,
                m_grid->gridIndex(),
                m_nativeFaultGenerator->quadToCellFaceMapper());

            texturer.createTextureCoords(m_nativeFaultFacesTextureCoords.p());

            const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper();
            RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_nativeFaultFaces.p(), m_nativeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode(), eclipseView->isLightingDisabled());
        }
        else
        {
            RivTextureCoordsCreator texturer(cellResultColors, 
                timeStepIndex, 
                m_grid->gridIndex(),  
                m_nativeFaultGenerator->quadToCellFaceMapper());

            if (!texturer.isValid())
            {
                return;
            }

            texturer.createTextureCoords(m_nativeFaultFacesTextureCoords.p());

            const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper();
            RivScalarMapperUtils::applyTextureResultsToPart(m_nativeFaultFaces.p(), m_nativeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode(), eclipseView->isLightingDisabled());
        }
    }

    if (m_oppositeFaultFaces.notNull())
    {
        if (cellResultColors->isTernarySaturationSelected())
        {
            RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(),
                timeStepIndex,
                m_grid->gridIndex(),
                m_oppositeFaultGenerator->quadToCellFaceMapper());

            texturer.createTextureCoords(m_oppositeFaultFacesTextureCoords.p());

            const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper();
            RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_oppositeFaultFaces.p(), m_oppositeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode(), eclipseView->isLightingDisabled());
        }
        else
        {
            RivTextureCoordsCreator texturer(cellResultColors,
                timeStepIndex,
                m_grid->gridIndex(),
                m_oppositeFaultGenerator->quadToCellFaceMapper());

            if (!texturer.isValid())
            {
                return;
            }

            texturer.createTextureCoords(m_oppositeFaultFacesTextureCoords.p());

            const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper();
            RivScalarMapperUtils::applyTextureResultsToPart(m_oppositeFaultFaces.p(), m_oppositeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode(), eclipseView->isLightingDisabled());
        }
    }
}
Пример #3
0
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanColorInterpolatedSurfacePart(const RimEclipseView& activeView)
{
    CVF_ASSERT(m_rimFracture);
    RimStimPlanFractureTemplate* stimPlanFracTemplate =
        dynamic_cast<RimStimPlanFractureTemplate*>(m_rimFracture->fractureTemplate());
    CVF_ASSERT(stimPlanFracTemplate);

    auto displayCoordTransform = activeView.displayCoordTransform();
    if (displayCoordTransform.isNull()) return nullptr;

    // Note that the filtering and result mapping code below couples closely to the triangulation and vertex layout returned by
    // triangleGeometry() If this ever changes, the entire code must be revisited
    std::vector<cvf::uint>  triangleIndices;
    std::vector<cvf::Vec3f> nodeDisplayCoords;
    {
        std::vector<cvf::Vec3f> nodeCoords;
        stimPlanFracTemplate->fractureTriangleGeometry(&nodeCoords, &triangleIndices);

        if (triangleIndices.empty() || nodeCoords.empty())
        {
            return nullptr;
        }

        cvf::Mat4d fractureXf = m_rimFracture->transformMatrix();
        nodeDisplayCoords     = transformToFractureDisplayCoords(nodeCoords, fractureXf, *displayCoordTransform);
    }

    RimRegularLegendConfig* legendConfig = nullptr;
    if (activeView.fractureColors() && activeView.fractureColors()->isChecked())
    {
        legendConfig = activeView.fractureColors()->activeLegend();
    }

    // Show selected result on the surface geometry and filter out triangles that have result values near 0
    if (legendConfig)
    {
        // Construct array with per node result values that correspond to the node coordinates of the triangle mesh
        // Since some time steps don't have result vales, we initialize the array to well known values before populating it
        std::vector<double> perNodeResultValues(nodeDisplayCoords.size(), HUGE_VAL);
        {
            size_t idx = 0;

            const std::vector<std::vector<double>> dataToPlot =
                stimPlanFracTemplate->resultValues(activeView.fractureColors()->uiResultName(),
                                                   activeView.fractureColors()->unit(),
                                                   stimPlanFracTemplate->activeTimeStepIndex());
            for (const std::vector<double>& dataAtY : dataToPlot)
            {
                for (double val : dataAtY)
                {
                    perNodeResultValues[idx++] = val;
                }
            }
        }
        CVF_ASSERT(perNodeResultValues.size() == nodeDisplayCoords.size());

        std::vector<cvf::uint> triIndicesToInclude;
        for (size_t i = 0; i < triangleIndices.size(); i += 6)
        {
            // Include all triangles where at least one of the vertices in the triangle pair has a value above threshold
            bool includeThisTrianglePair = false;
            for (size_t j = 0; j < 6; j++)
            {
                if (perNodeResultValues[triangleIndices[i + j]] > 1e-7)
                {
                    includeThisTrianglePair = true;
                }
            }

            if (includeThisTrianglePair)
            {
                for (size_t j = 0; j < 6; j++)
                {
                    triIndicesToInclude.push_back(triangleIndices[i + j]);
                }
            }
        }

        if (triIndicesToInclude.empty())
        {
            return nullptr;
        }

        cvf::ref<cvf::DrawableGeo> geo          = buildDrawableGeoFromTriangles(triIndicesToInclude, nodeDisplayCoords);
        const cvf::ScalarMapper*   scalarMapper = legendConfig->scalarMapper();
        CVF_ASSERT(scalarMapper);

        cvf::ref<cvf::Vec2fArray> textureCoords = new cvf::Vec2fArray(nodeDisplayCoords.size());
        textureCoords->setAll(cvf::Vec2f(0.5f, 1.0f));
        for (size_t i = 0; i < perNodeResultValues.size(); i++)
        {
            const double val = perNodeResultValues[i];
            if (val < HUGE_VAL && val == val)
            {
                textureCoords->set(i, scalarMapper->mapToTextureCoord(val));
            }
        }
        geo->setTextureCoordArray(textureCoords.p());

        cvf::ref<cvf::Part> surfacePart =
            createScalarMapperPart(geo.p(), scalarMapper, m_rimFracture, activeView.isLightingDisabled());

        return surfacePart;
    }
    else
    {
        // No result is mapped, show the entire StimPlan surface with default color

        return createSingleColorSurfacePart(triangleIndices, nodeDisplayCoords, activeView.fractureColors()->defaultColor());
    }
}
Пример #4
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RivCrossSectionPartMgr::updateCellResultColor(size_t timeStepIndex)
{
    if (m_crossSectionGenerator.isNull()) return;

    if (!m_crossSectionGenerator->isAnyGeometryPresent()) return;

    RimEclipseView* eclipseView;
    m_rimCrossSection->firstAnchestorOrThisOfType(eclipseView);

    if (eclipseView)
    {
        RimEclipseCellColors* cellResultColors = eclipseView->cellResult();
        CVF_ASSERT(cellResultColors);

        RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultColors->porosityModel());
        RigCaseData* eclipseCase = eclipseView->eclipseCase()->reservoirData();

        // CrossSections
        if (m_crossSectionFaces.notNull())
        {
            if (cellResultColors->isTernarySaturationSelected())
            {
                RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(), timeStepIndex);
                
                texturer.createTextureCoords(m_crossSectionFacesTextureCoords.p(), m_crossSectionGenerator->triangleToCellIndex());

                const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper();
                RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_crossSectionFaces.p(),
                                                                       m_crossSectionFacesTextureCoords.p(),
                                                                       mapper,
                                                                       1.0,
                                                                       caf::FC_NONE,
                                                                       eclipseView->isLightingDisabled());
            }
            else
            {
                CVF_ASSERT(m_crossSectionGenerator.notNull());

                const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper();
                cvf::ref<RigResultAccessor> resultAccessor;

                if (RimDefines::isPerCellFaceResult(cellResultColors->resultVariable()))
                {
                    resultAccessor = new RigHugeValResultAccessor;
                }
                else
                {
                    resultAccessor = RigResultAccessorFactory::createResultAccessor(cellResultColors->reservoirView()->eclipseCase()->reservoirData(),
                                                                                    0,
                                                                                    timeStepIndex,
                                                                                    cellResultColors);
                }

                RivCrossSectionPartMgr::calculateEclipseTextureCoordinates(m_crossSectionFacesTextureCoords.p(),
                                                                            m_crossSectionGenerator->triangleToCellIndex(),
                                                                            resultAccessor.p(),
                                                                            mapper);


                RivScalarMapperUtils::applyTextureResultsToPart(m_crossSectionFaces.p(),
                                                                m_crossSectionFacesTextureCoords.p(),
                                                                mapper,
                                                                1.0,
                                                                caf::FC_NONE,
                                                                eclipseView->isLightingDisabled());
                }
        }
    }

    RimGeoMechView* geoView;
    m_rimCrossSection->firstAnchestorOrThisOfType(geoView);

    if (geoView)
    {
        RimGeoMechCellColors* cellResultColors = geoView->cellResult();
        RigGeoMechCaseData* caseData = cellResultColors->ownerCaseData();
        
        if (!caseData) return;

        RigFemResultAddress      resVarAddress = cellResultColors->resultAddress();

        // Do a "Hack" to show elm nodal and not nodal POR results
        if (resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar") resVarAddress.resultPosType = RIG_ELEMENT_NODAL;

        const std::vector<RivVertexWeights> &vertexWeights = m_crossSectionGenerator->triangleVxToCellCornerInterpolationWeights();
        const std::vector<float>& resultValues             = caseData->femPartResults()->resultValues(resVarAddress, 0, (int)timeStepIndex);
        bool isElementNodalResult                          = !(resVarAddress.resultPosType == RIG_NODAL);
        RigFemPart* femPart                                = caseData->femParts()->part(0);
        const cvf::ScalarMapper* mapper                    = cellResultColors->legendConfig()->scalarMapper();

        RivCrossSectionPartMgr::calculateGeoMechTextureCoords(m_crossSectionFacesTextureCoords.p(), 
                                                              vertexWeights, 
                                                              resultValues, 
                                                              isElementNodalResult, 
                                                              femPart, 
                                                              mapper);

        RivScalarMapperUtils::applyTextureResultsToPart(m_crossSectionFaces.p(), 
                                                        m_crossSectionFacesTextureCoords.p(), 
                                                        mapper, 
                                                        1.0, 
                                                        caf::FC_NONE, 
                                                        geoView->isLightingDisabled());
    }
}