mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#1585 Add visualization (gray out) inactive parts of fractures based on containment.
This commit is contained in:
parent
63b478b18d
commit
fc05dd665f
@ -21,10 +21,14 @@
|
||||
#include "RiaApplication.h"
|
||||
|
||||
#include "RigFractureGrid.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RigHexIntersectionTools.h"
|
||||
#include "RigCellGeometryTools.h"
|
||||
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimEclipseWell.h"
|
||||
#include "RimFracture.h"
|
||||
#include "RimFractureContainment.h"
|
||||
#include "RimFractureTemplate.h"
|
||||
#include "RimLegendConfig.h"
|
||||
#include "RigFractureCell.h"
|
||||
@ -39,13 +43,16 @@
|
||||
#include "cafEffectGenerator.h"
|
||||
|
||||
#include "cvfDrawableGeo.h"
|
||||
#include "cvfGeometryTools.h"
|
||||
#include "cvfModelBasicList.h"
|
||||
#include "cvfPart.h"
|
||||
#include "cvfPrimitiveSet.h"
|
||||
#include "cvfPrimitiveSetDirect.h"
|
||||
#include "cvfPrimitiveSetIndexedUInt.h"
|
||||
#include "cvfScalarMapperContinuousLinear.h"
|
||||
#include "cvfRenderStateDepth.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
@ -101,6 +108,127 @@ void RivWellFracturePartMgr::generateSurfacePart(const caf::DisplayCoordTransfor
|
||||
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RivWellFracturePartMgr::generateContainmentMaskPart(const RimEclipseView* activeView)
|
||||
{
|
||||
std::vector<cvf::Vec3f> borderPolygonLocalCS = m_rimFracture->fractureTemplate()->fractureBorderPolygon(m_rimFracture->fractureUnit());
|
||||
cvf::Mat4d frMx = m_rimFracture->transformMatrix();
|
||||
|
||||
cvf::BoundingBox frBBox;
|
||||
std::vector<cvf::Vec3d> borderPolygonGlobCs;
|
||||
std::vector<cvf::Vec3d> borderPolygonLocalCsd;
|
||||
for (const auto& pv: borderPolygonLocalCS)
|
||||
{
|
||||
cvf::Vec3d pvd(pv);
|
||||
borderPolygonLocalCsd.push_back(pvd);
|
||||
pvd.transformPoint(frMx);
|
||||
borderPolygonGlobCs.push_back(pvd);
|
||||
frBBox.add(pvd);
|
||||
}
|
||||
|
||||
std::vector<size_t> cellCandidates;
|
||||
activeView->mainGrid()->findIntersectingCells(frBBox, &cellCandidates);
|
||||
|
||||
auto displCoordTrans = activeView->displayCoordTransform();
|
||||
|
||||
std::vector<cvf::Vec3f> maskTriangles;
|
||||
|
||||
for (size_t resCellIdx : cellCandidates)
|
||||
{
|
||||
if (!m_rimFracture->isEclipseCellWithinContainment(activeView->mainGrid(), resCellIdx))
|
||||
{
|
||||
// Calculat Eclipse cell intersection with fracture plane
|
||||
|
||||
std::array<cvf::Vec3d,8> corners;
|
||||
activeView->mainGrid()->cellCornerVertices(resCellIdx, corners.data());
|
||||
|
||||
std::vector<std::vector<cvf::Vec3d> > eclCellPolygons;
|
||||
bool hasIntersection = RigHexIntersectionTools::planeHexIntersectionPolygons(corners, frMx, eclCellPolygons);
|
||||
|
||||
if (!hasIntersection || eclCellPolygons.empty()) continue;
|
||||
|
||||
// Transform eclCell - plane intersection onto fracture
|
||||
|
||||
cvf::Mat4d invertedTransformMatrix = frMx.getInverted();
|
||||
for ( std::vector<cvf::Vec3d>& eclCellPolygon : eclCellPolygons )
|
||||
{
|
||||
for ( cvf::Vec3d& v : eclCellPolygon )
|
||||
{
|
||||
v.transformPoint(invertedTransformMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
cvf::Vec3d fractureNormal = cvf::Vec3d(frMx.col(2));
|
||||
cvf::Vec3d maskOffset = fractureNormal * 0.01 * frBBox.radius();
|
||||
for (const std::vector<cvf::Vec3d>& eclCellPolygon : eclCellPolygons)
|
||||
{
|
||||
// Clip Eclipse cell polygon with fracture border
|
||||
|
||||
std::vector< std::vector<cvf::Vec3d> > clippedPolygons = RigCellGeometryTools::intersectPolygons(eclCellPolygon,
|
||||
borderPolygonLocalCsd);
|
||||
for (auto& clippedPolygon : clippedPolygons)
|
||||
{
|
||||
for (auto& v: clippedPolygon)
|
||||
{
|
||||
v.transformPoint(frMx);
|
||||
}
|
||||
}
|
||||
|
||||
// Create triangles from the clipped polygons
|
||||
|
||||
for (auto& clippedPolygon : clippedPolygons)
|
||||
{
|
||||
cvf::EarClipTesselator tess;
|
||||
tess.setNormal(fractureNormal);
|
||||
cvf::Vec3dArray cvfNodes(clippedPolygon);
|
||||
tess.setGlobalNodeArray(cvfNodes);
|
||||
std::vector<size_t> polyIndexes;
|
||||
for (size_t idx = 0; idx < clippedPolygon.size(); ++idx) polyIndexes.push_back(idx);
|
||||
tess.setPolygonIndices(polyIndexes);
|
||||
|
||||
std::vector<size_t> triangleIndices;
|
||||
tess.calculateTriangles(&triangleIndices);
|
||||
|
||||
for (size_t idx: triangleIndices)
|
||||
{
|
||||
maskTriangles.push_back( cvf::Vec3f( displCoordTrans->transformToDisplayCoord(clippedPolygon[idx] + maskOffset)) );
|
||||
}
|
||||
|
||||
for (size_t idx: triangleIndices)
|
||||
{
|
||||
maskTriangles.push_back( cvf::Vec3f( displCoordTrans->transformToDisplayCoord(clippedPolygon[idx] - maskOffset)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( maskTriangles.size() >= 3 )
|
||||
{
|
||||
cvf::ref<cvf::DrawableGeo> maskTriangleGeo = new cvf::DrawableGeo;
|
||||
maskTriangleGeo->setVertexArray(new cvf::Vec3fArray(maskTriangles));
|
||||
|
||||
cvf::ref<cvf::PrimitiveSetDirect> primitives = new cvf::PrimitiveSetDirect(cvf::PT_TRIANGLES);
|
||||
primitives->setIndexCount(maskTriangles.size());
|
||||
maskTriangleGeo->addPrimitiveSet(primitives.p());
|
||||
maskTriangleGeo->computeNormals();
|
||||
|
||||
m_containmentMaskPart = new cvf::Part(0, "FractureContainmentMaskPart");
|
||||
m_containmentMaskPart->setDrawable(maskTriangleGeo.p());
|
||||
m_containmentMaskPart->setSourceInfo(new RivObjectSourceInfo(m_rimFracture));
|
||||
|
||||
cvf::Color4f maskColor = cvf::Color4f(cvf::Color3f(cvf::Color3::GRAY));
|
||||
|
||||
caf::SurfaceEffectGenerator surfaceGen(maskColor, caf::PO_NONE);
|
||||
cvf::ref<cvf::Effect> eff = surfaceGen.generateCachedEffect();
|
||||
m_containmentMaskPart->setEffect(eff.p());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -455,6 +583,15 @@ void RivWellFracturePartMgr::appendGeometryPartsToModel(cvf::ModelBasicList* mod
|
||||
generateSurfacePart(displayCoordTransform.p());
|
||||
applyFractureUniformColor(eclView);
|
||||
}
|
||||
|
||||
if (m_rimFracture->fractureTemplate()->fractureContainment()->isEnabled())
|
||||
{
|
||||
generateContainmentMaskPart(eclView);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_containmentMaskPart = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -475,6 +612,11 @@ void RivWellFracturePartMgr::appendGeometryPartsToModel(cvf::ModelBasicList* mod
|
||||
{
|
||||
model->addPart(m_polygonPart.p());
|
||||
}
|
||||
|
||||
if (m_containmentMaskPart.notNull())
|
||||
{
|
||||
model->addPart(m_containmentMaskPart.p());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
private:
|
||||
void generateSurfacePart(const caf::DisplayCoordTransform* displayCoordTransform);
|
||||
|
||||
void generateContainmentMaskPart(const RimEclipseView* activeView);
|
||||
void applyFractureUniformColor(const RimEclipseView* activeView);
|
||||
|
||||
void applyResultTextureColor(const RimEclipseView* activeView);
|
||||
@ -99,6 +100,7 @@ private:
|
||||
caf::PdmPointer<RimFracture> m_rimFracture;
|
||||
|
||||
cvf::ref<cvf::Part> m_surfacePart;
|
||||
cvf::ref<cvf::Part> m_containmentMaskPart;
|
||||
cvf::ref<cvf::Part> m_polygonPart;
|
||||
cvf::ref<cvf::Part> m_stimPlanMeshPart;
|
||||
};
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "RimFractureContainment.h"
|
||||
#include "cafPdmUiSliderEditor.h"
|
||||
#include "RigMainGrid.h"
|
||||
#include "RimProject.h"
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimFractureContainment, "FractureContainment");
|
||||
@ -122,3 +123,17 @@ void RimFractureContainment::defineUiOrdering(QString uiConfigName, caf::PdmUiOr
|
||||
//uiOrdering.add(&m_faultTruncation);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureContainment::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
if (changedField == &m_isUsingFractureContainment
|
||||
|| m_isUsingFractureContainment())
|
||||
{
|
||||
RimProject* proj;
|
||||
this->firstAncestorOrThisOfType(proj);
|
||||
if (proj) proj->createDisplayModelAndRedrawAllViews();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,9 +42,10 @@ public:
|
||||
bool isEclipseCellWithinContainment(const RigMainGrid* mainGrid, size_t anchorEclipseCell, size_t globalCellIndex) const;
|
||||
|
||||
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;
|
||||
|
||||
private:
|
||||
|
@ -448,6 +448,7 @@ void RimEclipseView::createDisplayModel()
|
||||
addWellPathsToModel(m_wellPathPipeVizModel.p(), currentActiveCellInfo()->geometryBoundingBox());
|
||||
|
||||
wellPathsPartManager()->appendStaticFracturePartsToModel(m_wellPathPipeVizModel.p(), this);
|
||||
m_wellPathPipeVizModel->updateBoundingBoxesRecursive();
|
||||
|
||||
m_viewer->addStaticModelOnce(m_wellPathPipeVizModel.p());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user