#1585 Add visualization (gray out) inactive parts of fractures based on containment.

This commit is contained in:
Jacob Støren 2017-06-27 13:19:21 +02:00
parent 63b478b18d
commit fc05dd665f
5 changed files with 162 additions and 1 deletions

View File

@ -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());
}
}
//--------------------------------------------------------------------------------------------------

View File

@ -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;
};

View File

@ -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();
}
}

View File

@ -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:

View File

@ -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());