#2481, #2605, #2486 Use a flattened version of the normal wellpath visualization in 2D intersection view

This commit is contained in:
Jacob Støren 2018-03-20 13:12:20 +01:00
parent 0de43ac938
commit a9daea0938
10 changed files with 360 additions and 200 deletions

View File

@ -794,7 +794,7 @@ void RivIntersectionPartMgr::appendWellPipePartsToModel(cvf::ModelBasicList* mod
createSourceInfoFunc = [&](size_t brIdx) { return new RivSimWellPipeSourceInfo(simWellInView, brIdx); }; createSourceInfoFunc = [&](size_t brIdx) { return new RivSimWellPipeSourceInfo(simWellInView, brIdx); };
characteristicCellSize = eclView->eclipseCase()->characteristicCellSize(); characteristicCellSize = eclView->eclipseCase()->characteristicCellSize();
} }
else if (m_rimCrossSection->type() == RimIntersection::CS_WELL_PATH) else if (false)//m_rimCrossSection->type() == RimIntersection::CS_WELL_PATH)
{ {
RimWellPath* wellPath = m_rimCrossSection->wellPath(); RimWellPath* wellPath = m_rimCrossSection->wellPath();
@ -816,9 +816,10 @@ void RivIntersectionPartMgr::appendWellPipePartsToModel(cvf::ModelBasicList* mod
// Create pipe geometry // Create pipe geometry
if ( //m_rimCrossSection->type() == RimIntersection::CS_SIMULATION_WELL if ( false //m_rimCrossSection->type() == RimIntersection::CS_SIMULATION_WELL
//|| //||
m_rimCrossSection->type() == RimIntersection::CS_WELL_PATH ) //m_rimCrossSection->type() == RimIntersection::CS_WELL_PATH
)
{ {
std::vector<std::vector<cvf::Vec3d> > polyLines = m_crossSectionGenerator->flattenedOrOffsettedPolyLines(); std::vector<std::vector<cvf::Vec3d> > polyLines = m_crossSectionGenerator->flattenedOrOffsettedPolyLines();

View File

@ -48,6 +48,7 @@
#include "RivObjectSourceInfo.h" #include "RivObjectSourceInfo.h"
#include "RivPartPriority.h" #include "RivPartPriority.h"
#include "RivPipeGeometryGenerator.h" #include "RivPipeGeometryGenerator.h"
#include "RivSectionFlattner.h"
#include "RivWellConnectionFactorPartMgr.h" #include "RivWellConnectionFactorPartMgr.h"
#include "RivWellFracturePartMgr.h" #include "RivWellFracturePartMgr.h"
#include "RivWellPathPartMgr.h" #include "RivWellPathPartMgr.h"
@ -256,7 +257,8 @@ void RivWellPathPartMgr::appendVirtualTransmissibilitiesToModel(cvf::ModelBasicL
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RivWellPathPartMgr::buildWellPathParts(const caf::DisplayCoordTransform* displayCoordTransform, void RivWellPathPartMgr::buildWellPathParts(const caf::DisplayCoordTransform* displayCoordTransform,
double characteristicCellSize, double characteristicCellSize,
const cvf::BoundingBox& wellPathClipBoundingBox) const cvf::BoundingBox& wellPathClipBoundingBox,
bool doFlatten)
{ {
RimWellPathCollection* wellPathCollection = this->wellPathCollection(); RimWellPathCollection* wellPathCollection = this->wellPathCollection();
if (!wellPathCollection) return; if (!wellPathCollection) return;
@ -264,39 +266,71 @@ void RivWellPathPartMgr::buildWellPathParts(const caf::DisplayCoordTransform* di
RigWellPath* wellPathGeometry = m_rimWellPath->wellPathGeometry(); RigWellPath* wellPathGeometry = m_rimWellPath->wellPathGeometry();
if (!wellPathGeometry) return; if (!wellPathGeometry) return;
if (wellPathGeometry->m_wellPathPoints.size() < 2) return; const std::vector<cvf::Vec3d>& wellpathCenterLine = wellPathGeometry->m_wellPathPoints;
if (wellpathCenterLine.size() < 2) return;
clearAllBranchData(); clearAllBranchData();
double wellPathRadius = this->wellPathRadius(characteristicCellSize, wellPathCollection); double wellPathRadius = this->wellPathRadius(characteristicCellSize, wellPathCollection);
cvf::Vec3d textPosition;
// Generate the well path geometry as a line and pipe structure // Generate the well path geometry as a line and pipe structure
{
m_pipeGeomGenerator = new RivPipeGeometryGenerator; m_pipeGeomGenerator = new RivPipeGeometryGenerator;
m_pipeGeomGenerator->setRadius(wellPathRadius); m_pipeGeomGenerator->setRadius(wellPathRadius);
m_pipeGeomGenerator->setCrossSectionVertexCount(wellPathCollection->wellPathCrossSectionVertexCount()); m_pipeGeomGenerator->setCrossSectionVertexCount(wellPathCollection->wellPathCrossSectionVertexCount());
cvf::ref<cvf::Vec3dArray> cvfCoords = new cvf::Vec3dArray; double horizontalLengthAlongWellToClipPoint = 0.0;
if (wellPathCollection->wellPathClip)
std::vector<cvf::Vec3d> clippedWellPathCenterLine;
// Skip visualization if outside the domain of this case
{ {
cvf::Vec3d casemax = wellPathClipBoundingBox.max();
cvf::Vec3d casemin = wellPathClipBoundingBox.min();
cvf::Vec3d caseext = wellPathClipBoundingBox.extent();
// Add up to the sealevel
cvf::BoundingBox relevantWellpathBBox = wellPathClipBoundingBox;
relevantWellpathBBox.add(cvf::Vec3d(casemax.x(), casemax.y(), 0.0));
// Add some sideways leeway
cvf::Vec3d addSize = 3.0*cvf::Vec3d(caseext.x(), caseext.y(), 0.0);
relevantWellpathBBox.add(casemax + addSize);
relevantWellpathBBox.add(casemin - addSize);
if ( !RigWellPath::isPolylineTouchingBBox(wellpathCenterLine, relevantWellpathBBox) )
{
return;
}
}
if ( wellPathCollection->wellPathClip )
{
double maxZClipHeight = wellPathClipBoundingBox.max().z() + wellPathCollection->wellPathClipZDistance;
clippedWellPathCenterLine = RigWellPath::clipPolylineStartAboveZ(wellpathCenterLine,
maxZClipHeight,
&horizontalLengthAlongWellToClipPoint);
#if 0
size_t firstVisibleSegmentIndex = cvf::UNDEFINED_SIZE_T; size_t firstVisibleSegmentIndex = cvf::UNDEFINED_SIZE_T;
for (size_t idx = 0; idx < wellPathGeometry->m_wellPathPoints.size(); idx++) for ( size_t idx = 0; idx < wellPathGeometry->m_wellPathPoints.size(); idx++ )
{ {
cvf::Vec3d point = wellPathGeometry->m_wellPathPoints[idx]; cvf::Vec3d point = wellPathGeometry->m_wellPathPoints[idx];
if (point.z() < (wellPathClipBoundingBox.max().z() + wellPathCollection->wellPathClipZDistance)) if ( point.z() < (wellPathClipBoundingBox.max().z() + wellPathCollection->wellPathClipZDistance) )
{ {
firstVisibleSegmentIndex = idx; firstVisibleSegmentIndex = idx;
break; break;
} }
} }
std::vector<cvf::Vec3d> clippedPoints;
if (firstVisibleSegmentIndex != cvf::UNDEFINED_SIZE_T)
if ( firstVisibleSegmentIndex != cvf::UNDEFINED_SIZE_T )
{ {
if (firstVisibleSegmentIndex > 0) if ( firstVisibleSegmentIndex > 0 )
{ {
double wellPathStartPoint = wellPathClipBoundingBox.max().z() + wellPathCollection->wellPathClipZDistance; double wellPathStartPoint = wellPathClipBoundingBox.max().z() + wellPathCollection->wellPathClipZDistance;
double stepsize = (wellPathStartPoint - wellPathGeometry->m_wellPathPoints[firstVisibleSegmentIndex - 1].z()) / double stepsize = (wellPathStartPoint - wellPathGeometry->m_wellPathPoints[firstVisibleSegmentIndex - 1].z()) /
@ -313,35 +347,54 @@ void RivWellPathPartMgr::buildWellPathParts(const caf::DisplayCoordTransform* di
m_pipeGeomGenerator->setFirstVisibleSegmentIndex(firstVisibleSegmentIndex); m_pipeGeomGenerator->setFirstVisibleSegmentIndex(firstVisibleSegmentIndex);
} }
for (size_t idx = firstVisibleSegmentIndex; idx < wellPathGeometry->m_wellPathPoints.size(); idx++) for ( size_t idx = firstVisibleSegmentIndex; idx < wellPathGeometry->m_wellPathPoints.size(); idx++ )
{ {
clippedPoints.push_back(wellPathGeometry->m_wellPathPoints[idx]); clippedPoints.push_back(wellPathGeometry->m_wellPathPoints[idx]);
} }
} }
#endif
if (clippedPoints.size() < 2) return;
cvfCoords->assign(clippedPoints);
} }
else else
{ {
cvfCoords->assign(wellPathGeometry->m_wellPathPoints); clippedWellPathCenterLine = wellpathCenterLine;
} }
if ( clippedWellPathCenterLine.size() < 2 ) return;
cvf::ref<cvf::Vec3dArray> cvfCoords = new cvf::Vec3dArray(clippedWellPathCenterLine.size());
// Scale the centerline coordinates using the Z-scale transform of the grid and correct for the display offset. // Scale the centerline coordinates using the Z-scale transform of the grid and correct for the display offset.
for (size_t cIdx = 0; cIdx < cvfCoords->size(); ++cIdx)
{
(*cvfCoords)[cIdx] = displayCoordTransform->transformToDisplayCoord((*cvfCoords)[cIdx]);
}
textPosition = cvfCoords->get(0); if ( doFlatten )
{
cvf::Vec3d dummy;
std::vector<cvf::Mat4d> flatningCSs =
RivSectionFlattner::calculateFlatteningCSsForPolyline(clippedWellPathCenterLine,
cvf::Vec3d::Z_AXIS,
{ horizontalLengthAlongWellToClipPoint, 0.0, clippedWellPathCenterLine[0].z() },
&dummy);
for ( size_t cIdx = 0; cIdx < cvfCoords->size(); ++cIdx )
{
auto clpoint = clippedWellPathCenterLine[cIdx].getTransformedPoint(flatningCSs[cIdx]);
(*cvfCoords)[cIdx] = displayCoordTransform->scaleToDisplaySize(clpoint);
}
}
else
{
for ( size_t cIdx = 0; cIdx < cvfCoords->size(); ++cIdx )
{
(*cvfCoords)[cIdx] = displayCoordTransform->transformToDisplayCoord(clippedWellPathCenterLine[cIdx]);
}
}
m_pipeGeomGenerator->setPipeCenterCoords(cvfCoords.p()); m_pipeGeomGenerator->setPipeCenterCoords(cvfCoords.p());
m_surfaceDrawable = m_pipeGeomGenerator->createPipeSurface(); m_surfaceDrawable = m_pipeGeomGenerator->createPipeSurface();
m_centerLineDrawable = m_pipeGeomGenerator->createCenterLine(); m_centerLineDrawable = m_pipeGeomGenerator->createCenterLine();
if (m_surfaceDrawable.notNull()) if ( m_surfaceDrawable.notNull() )
{ {
m_surfacePart = new cvf::Part; m_surfacePart = new cvf::Part;
m_surfacePart->setDrawable(m_surfaceDrawable.p()); m_surfacePart->setDrawable(m_surfaceDrawable.p());
@ -355,7 +408,7 @@ void RivWellPathPartMgr::buildWellPathParts(const caf::DisplayCoordTransform* di
m_surfacePart->setEffect(eff.p()); m_surfacePart->setEffect(eff.p());
} }
if (m_centerLineDrawable.notNull()) if ( m_centerLineDrawable.notNull() )
{ {
m_centerLinePart = new cvf::Part; m_centerLinePart = new cvf::Part;
m_centerLinePart->setDrawable(m_centerLineDrawable.p()); m_centerLinePart->setDrawable(m_centerLineDrawable.p());
@ -365,10 +418,10 @@ void RivWellPathPartMgr::buildWellPathParts(const caf::DisplayCoordTransform* di
m_centerLinePart->setEffect(eff.p()); m_centerLinePart->setEffect(eff.p());
} }
}
// Generate label with well-path name // Generate label with well-path name
cvf::Vec3d textPosition = cvfCoords->get(0);
textPosition.z() += 2.2 * characteristicCellSize; textPosition.z() += 2.2 * characteristicCellSize;
if (wellPathCollection->showWellPathLabel() && m_rimWellPath->showWellPathLabel() && !m_rimWellPath->name().isEmpty()) if (wellPathCollection->showWellPathLabel() && m_rimWellPath->showWellPathLabel() && !m_rimWellPath->name().isEmpty())
@ -421,7 +474,7 @@ void RivWellPathPartMgr::appendStaticGeometryPartsToModel(cvf::ModelBasicList*
return; return;
// The pipe geometry needs to be rebuilt on scale change to keep the pipes round // The pipe geometry needs to be rebuilt on scale change to keep the pipes round
buildWellPathParts(displayCoordTransform, characteristicCellSize, wellPathClipBoundingBox); buildWellPathParts(displayCoordTransform, characteristicCellSize, wellPathClipBoundingBox, false);
if (m_surfacePart.notNull()) if (m_surfacePart.notNull())
{ {
@ -442,6 +495,33 @@ void RivWellPathPartMgr::appendStaticGeometryPartsToModel(cvf::ModelBasicList*
appendImportedFishbonesToModel(model, displayCoordTransform, characteristicCellSize); appendImportedFishbonesToModel(model, displayCoordTransform, characteristicCellSize);
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivWellPathPartMgr::appendFlattenedStaticGeometryPartsToModel(cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform,
double characteristicCellSize,
const cvf::BoundingBox& wellPathClipBoundingBox)
{
// The pipe geometry needs to be rebuilt on scale change to keep the pipes round
buildWellPathParts(displayCoordTransform, characteristicCellSize, wellPathClipBoundingBox, true);
if (m_surfacePart.notNull())
{
model->addPart(m_surfacePart.p());
}
if (m_centerLinePart.notNull())
{
model->addPart(m_centerLinePart.p());
}
if (m_wellLabelPart.notNull())
{
model->addPart(m_wellLabelPart.p());
}
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -64,6 +64,10 @@ public:
double characteristicCellSize, double characteristicCellSize,
const cvf::BoundingBox& wellPathClipBoundingBox); const cvf::BoundingBox& wellPathClipBoundingBox);
void appendFlattenedStaticGeometryPartsToModel(cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform,
double characteristicCellSize,
const cvf::BoundingBox& wellPathClipBoundingBox);
void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model,
size_t timeStepIndex, size_t timeStepIndex,
@ -96,7 +100,8 @@ private:
void buildWellPathParts(const caf::DisplayCoordTransform* displayCoordTransform, void buildWellPathParts(const caf::DisplayCoordTransform* displayCoordTransform,
double characteristicCellSize, double characteristicCellSize,
const cvf::BoundingBox& wellPathClipBoundingBox); const cvf::BoundingBox& wellPathClipBoundingBox,
bool doFlatten);
void clearAllBranchData(); void clearAllBranchData();

View File

@ -17,19 +17,9 @@
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
#include "Rim2dIntersectionView.h" #include "Rim2dIntersectionView.h"
#include "Rim2dIntersectionViewCollection.h"
#include "RimIntersection.h"
#include "RimCase.h" #include "RimCase.h"
#include "RiuViewer.h" #include "RimIntersection.h"
#include "RimGridView.h" #include "RimGridView.h"
#include "RivIntersectionPartMgr.h"
#include "RivTernarySaturationOverlayItem.h"
#include "cvfPart.h"
#include "cvfModelBasicList.h"
#include "cvfTransform.h"
#include "cvfScene.h"
#include "Rim3dOverlayInfoConfig.h" #include "Rim3dOverlayInfoConfig.h"
#include "RimEclipseView.h" #include "RimEclipseView.h"
#include "RimEclipseCellColors.h" #include "RimEclipseCellColors.h"
@ -40,10 +30,22 @@
#include "RimSimWellInView.h" #include "RimSimWellInView.h"
#include "RimWellPath.h" #include "RimWellPath.h"
#include <QDateTime> #include "RiuViewer.h"
#include "cafDisplayCoordTransform.h"
#include "RivIntersectionPartMgr.h"
#include "RivTernarySaturationOverlayItem.h"
#include "RivSimWellPipesPartMgr.h" #include "RivSimWellPipesPartMgr.h"
#include "RivWellHeadPartMgr.h" #include "RivWellHeadPartMgr.h"
#include "RivWellPathPartMgr.h"
#include "cafDisplayCoordTransform.h"
#include "cvfModelBasicList.h"
#include "cvfTransform.h"
#include "cvfScene.h"
#include "cvfPart.h"
#include <QDateTime>
CAF_PDM_SOURCE_INIT(Rim2dIntersectionView, "Intersection2dView"); CAF_PDM_SOURCE_INIT(Rim2dIntersectionView, "Intersection2dView");
@ -292,6 +294,14 @@ void Rim2dIntersectionView::update3dInfo()
m_viewer->update(); m_viewer->update();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<RivIntersectionPartMgr> Rim2dIntersectionView::flatIntersectionPartMgr() const
{
return m_flatIntersectionPartMgr;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -395,6 +405,7 @@ void Rim2dIntersectionView::createDisplayModel()
m_flatIntersectionPartMgr = new RivIntersectionPartMgr(m_intersection(), true); m_flatIntersectionPartMgr = new RivIntersectionPartMgr(m_intersection(), true);
m_intersectionVizModel->removeAllParts(); m_intersectionVizModel->removeAllParts();
m_flatIntersectionPartMgr->appendNativeCrossSectionFacesToModel(m_intersectionVizModel.p(), scaleTransform()); m_flatIntersectionPartMgr->appendNativeCrossSectionFacesToModel(m_intersectionVizModel.p(), scaleTransform());
@ -420,6 +431,22 @@ void Rim2dIntersectionView::createDisplayModel()
} }
} }
m_flatWellpathPartMgr = nullptr;
if ( m_intersection->type() == RimIntersection::CS_WELL_PATH
&& m_intersection->wellPath() )
{
Rim3dView* settingsView = nullptr;
m_intersection->firstAncestorOrThisOfType(settingsView);
if ( settingsView )
{
m_flatWellpathPartMgr = new RivWellPathPartMgr(m_intersection->wellPath(), settingsView);
m_flatWellpathPartMgr->appendFlattenedStaticGeometryPartsToModel(m_intersectionVizModel.p(),
this->displayCoordTransform().p(),
this->ownerCase()->characteristicCellSize(),
this->ownerCase()->activeCellsBoundingBox());
}
}
m_viewer->addStaticModelOnce(m_intersectionVizModel.p()); m_viewer->addStaticModelOnce(m_intersectionVizModel.p());
m_intersectionVizModel->updateBoundingBoxesRecursive(); m_intersectionVizModel->updateBoundingBoxesRecursive();
@ -436,26 +463,6 @@ void Rim2dIntersectionView::createDisplayModel()
} }
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim2dIntersectionView::createPartCollectionFromSelection(cvf::Collection<cvf::Part>* parts)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim2dIntersectionView::onTimeStepChanged()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim2dIntersectionView::clampCurrentTimestep()
{
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -579,6 +586,26 @@ void Rim2dIntersectionView::resetLegendsInViewer()
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim2dIntersectionView::createPartCollectionFromSelection(cvf::Collection<cvf::Part>* parts)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim2dIntersectionView::onTimeStepChanged()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim2dIntersectionView::clampCurrentTimestep()
{
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -19,7 +19,6 @@
#pragma once #pragma once
#include "Rim3dView.h" #include "Rim3dView.h"
#include "RivIntersectionPartMgr.h"
#include "cafPdmPtrField.h" #include "cafPdmPtrField.h"
class RimIntersection; class RimIntersection;
@ -27,6 +26,8 @@ class RimLegendConfig;
class RimTernaryLegendConfig; class RimTernaryLegendConfig;
class RivSimWellPipesPartMgr; class RivSimWellPipesPartMgr;
class RivWellHeadPartMgr; class RivWellHeadPartMgr;
class RivWellPathPartMgr;
class RivIntersectionPartMgr;
namespace cvf namespace cvf
{ {
@ -60,7 +61,7 @@ public:
void update3dInfo(); void update3dInfo();
cvf::ref<RivIntersectionPartMgr> flatIntersectionPartMgr() const { return m_flatIntersectionPartMgr; } cvf::ref<RivIntersectionPartMgr> flatIntersectionPartMgr() const;
virtual cvf::ref<caf::DisplayCoordTransform> displayCoordTransform() const override; virtual cvf::ref<caf::DisplayCoordTransform> displayCoordTransform() const override;
@ -99,6 +100,7 @@ protected:
cvf::ref<RivIntersectionPartMgr> m_flatIntersectionPartMgr; cvf::ref<RivIntersectionPartMgr> m_flatIntersectionPartMgr;
cvf::ref<RivSimWellPipesPartMgr> m_flatSimWellPipePartMgr; cvf::ref<RivSimWellPipesPartMgr> m_flatSimWellPipePartMgr;
cvf::ref<RivWellHeadPartMgr> m_flatWellHeadPartMgr; cvf::ref<RivWellHeadPartMgr> m_flatWellHeadPartMgr;
cvf::ref<RivWellPathPartMgr> m_flatWellpathPartMgr;
cvf::ref<cvf::ModelBasicList> m_intersectionVizModel; cvf::ref<cvf::ModelBasicList> m_intersectionVizModel;
cvf::ref<cvf::Transform> m_scaleTransform; cvf::ref<cvf::Transform> m_scaleTransform;

View File

@ -403,7 +403,14 @@ std::vector< std::vector <cvf::Vec3d> > RimIntersection::polyLines(cvf::Vec3d *
if (wellPath() && wellPath->wellPathGeometry() ) if (wellPath() && wellPath->wellPathGeometry() )
{ {
lines.push_back(wellPath->wellPathGeometry()->m_wellPathPoints); lines.push_back(wellPath->wellPathGeometry()->m_wellPathPoints);
clipToReservoir(lines[0], &horizontalProjectedLengthAlongWellPathToClipPoint); RimCase* ownerCase = nullptr;
this->firstAncestorOrThisOfType(ownerCase);
if (ownerCase)
{
lines[0] = RigWellPath::clipPolylineStartAboveZ(lines[0],
ownerCase->activeCellsBoundingBox().max().z(),
&horizontalProjectedLengthAlongWellPathToClipPoint);
}
} }
} }
else if (type == CS_SIMULATION_WELL) else if (type == CS_SIMULATION_WELL)
@ -605,65 +612,6 @@ void RimIntersection::updateName()
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimIntersection::clipToReservoir(std::vector<cvf::Vec3d> &polyLine, double * horizontalLengthAlongWellToClipPoint) const
{
CVF_ASSERT(horizontalLengthAlongWellToClipPoint != nullptr);
*horizontalLengthAlongWellToClipPoint = 0.0;
RimCase* ownerCase = nullptr;
firstAncestorOrThisOfType(ownerCase);
std::vector<cvf::Vec3d> clippedPolyLine;
if (ownerCase)
{
cvf::BoundingBox caseBB = ownerCase->activeCellsBoundingBox();
bool hasEnteredReservoirBB = false;
for (size_t vxIdx = 0 ; vxIdx < polyLine.size(); ++vxIdx)
{
if (!caseBB.contains(polyLine[vxIdx]))
{
if (vxIdx > 0)
{
cvf::Vec3d segment = polyLine[vxIdx] - polyLine[vxIdx-1];
segment[2] = 0.0;
*horizontalLengthAlongWellToClipPoint += segment.length();
}
continue;
}
if (!hasEnteredReservoirBB)
{
if (vxIdx > 0)
{
// clip line, and add vx to start
cvf::Plane topPlane;
topPlane.setFromPointAndNormal(caseBB.max(), cvf::Vec3d::Z_AXIS);
cvf::Vec3d intersection;
if (topPlane.intersect(polyLine[vxIdx-1], polyLine[vxIdx], &intersection))
{
cvf::Vec3d segment = intersection - polyLine[vxIdx-1];
segment[2] = 0.0;
*horizontalLengthAlongWellToClipPoint += segment.length();
clippedPolyLine.push_back(intersection);
}
}
hasEnteredReservoirBB = true;
}
clippedPolyLine.push_back(polyLine[vxIdx]);
}
}
polyLine.swap(clippedPolyLine);
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -139,7 +139,6 @@ private:
void updateSimulationWellCenterline() const; void updateSimulationWellCenterline() const;
void updateWellExtentDefaultValue(); void updateWellExtentDefaultValue();
void addExtents(std::vector<cvf::Vec3d> &polyLine) const; void addExtents(std::vector<cvf::Vec3d> &polyLine) const;
void clipToReservoir(std::vector<cvf::Vec3d> &polyLinee, double * horizontalLengthAlongWellToClipPoint) const;
void updateName(); void updateName();
void rebuildGeometryAndScheduleCreateDisplayModel(); void rebuildGeometryAndScheduleCreateDisplayModel();
static double azimuthInRadians(cvf::Vec3d vec); static double azimuthInRadians(cvf::Vec3d vec);

View File

@ -17,9 +17,10 @@
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
#include "RigWellPath.h" #include "RigWellPath.h"
#include "cvfGeometryTools.h"
#include "cvfGeometryTools.h" #include "cvfGeometryTools.h"
#include "cvfBoundingBox.h"
#include "cvfPlane.h"
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
@ -63,14 +64,14 @@ cvf::Vec3d RigWellPath::interpolatedPointAlongWellPath(double measuredDepth) con
cvf::Vec3d wellPathPoint = cvf::Vec3d::ZERO; cvf::Vec3d wellPathPoint = cvf::Vec3d::ZERO;
size_t i = 0; size_t i = 0;
while (i < m_measuredDepths.size() && m_measuredDepths.at(i) < measuredDepth ) while ( i < m_measuredDepths.size() && m_measuredDepths.at(i) < measuredDepth )
{ {
i++; i++;
} }
if (m_measuredDepths.size() > i) if ( m_measuredDepths.size() > i )
{ {
if (i == 0) if ( i == 0 )
{ {
//For measuredDepth same or lower than first point, use this first point //For measuredDepth same or lower than first point, use this first point
wellPathPoint = m_wellPathPoints.at(0); wellPathPoint = m_wellPathPoints.at(0);
@ -101,13 +102,13 @@ double RigWellPath::wellPathAzimuthAngle(const cvf::Vec3d& position) const
size_t closestIndex = cvf::UNDEFINED_SIZE_T; size_t closestIndex = cvf::UNDEFINED_SIZE_T;
double closestDistance = cvf::UNDEFINED_DOUBLE; double closestDistance = cvf::UNDEFINED_DOUBLE;
for (size_t i = 1; i < m_wellPathPoints.size(); i++) for ( size_t i = 1; i < m_wellPathPoints.size(); i++ )
{ {
cvf::Vec3d p1 = m_wellPathPoints[i - 1]; cvf::Vec3d p1 = m_wellPathPoints[i - 1];
cvf::Vec3d p2 = m_wellPathPoints[i - 0]; cvf::Vec3d p2 = m_wellPathPoints[i - 0];
double candidateDistance = cvf::GeometryTools::linePointSquareDist(p1, p2, position); double candidateDistance = cvf::GeometryTools::linePointSquareDist(p1, p2, position);
if (candidateDistance < closestDistance) if ( candidateDistance < closestDistance )
{ {
closestDistance = candidateDistance; closestDistance = candidateDistance;
closestIndex = i; closestIndex = i;
@ -117,12 +118,12 @@ double RigWellPath::wellPathAzimuthAngle(const cvf::Vec3d& position) const
//For vertical well (x-component of direction = 0) returned angle will be 90. //For vertical well (x-component of direction = 0) returned angle will be 90.
double azimuthAngleDegrees = 90.0; double azimuthAngleDegrees = 90.0;
if (closestIndex != cvf::UNDEFINED_DOUBLE) if ( closestIndex != cvf::UNDEFINED_DOUBLE )
{ {
cvf::Vec3d p1; cvf::Vec3d p1;
cvf::Vec3d p2; cvf::Vec3d p2;
if (closestIndex > 0) if ( closestIndex > 0 )
{ {
p1 = m_wellPathPoints[closestIndex - 1]; p1 = m_wellPathPoints[closestIndex - 1];
p2 = m_wellPathPoints[closestIndex - 0]; p2 = m_wellPathPoints[closestIndex - 0];
@ -135,7 +136,7 @@ double RigWellPath::wellPathAzimuthAngle(const cvf::Vec3d& position) const
cvf::Vec3d direction = p2 - p1; cvf::Vec3d direction = p2 - p1;
if (fabs(direction.y()) > 1e-5) if ( fabs(direction.y()) > 1e-5 )
{ {
double atanValue = direction.x() / direction.y(); double atanValue = direction.x() / direction.y();
double azimuthRadians = atan(atanValue); double azimuthRadians = atan(atanValue);
@ -156,13 +157,13 @@ void RigWellPath::twoClosestPoints(const cvf::Vec3d& position, cvf::Vec3d* p1, c
size_t closestIndex = cvf::UNDEFINED_SIZE_T; size_t closestIndex = cvf::UNDEFINED_SIZE_T;
double closestDistance = cvf::UNDEFINED_DOUBLE; double closestDistance = cvf::UNDEFINED_DOUBLE;
for (size_t i = 1; i < m_wellPathPoints.size(); i++) for ( size_t i = 1; i < m_wellPathPoints.size(); i++ )
{ {
cvf::Vec3d p1 = m_wellPathPoints[i - 1]; cvf::Vec3d p1 = m_wellPathPoints[i - 1];
cvf::Vec3d p2 = m_wellPathPoints[i - 0]; cvf::Vec3d p2 = m_wellPathPoints[i - 0];
double candidateDistance = cvf::GeometryTools::linePointSquareDist(p1, p2, position); double candidateDistance = cvf::GeometryTools::linePointSquareDist(p1, p2, position);
if (candidateDistance < closestDistance) if ( candidateDistance < closestDistance )
{ {
closestDistance = candidateDistance; closestDistance = candidateDistance;
closestIndex = i; closestIndex = i;
@ -171,7 +172,7 @@ void RigWellPath::twoClosestPoints(const cvf::Vec3d& position, cvf::Vec3d* p1, c
if (closestIndex != cvf::UNDEFINED_SIZE_T) if (closestIndex != cvf::UNDEFINED_SIZE_T)
{ {
if (closestIndex > 0) if ( closestIndex > 0 )
{ {
*p1 = m_wellPathPoints[closestIndex - 1]; *p1 = m_wellPathPoints[closestIndex - 1];
*p2 = m_wellPathPoints[closestIndex - 0]; *p2 = m_wellPathPoints[closestIndex - 0];
@ -190,16 +191,16 @@ void RigWellPath::twoClosestPoints(const cvf::Vec3d& position, cvf::Vec3d* p1, c
std::pair<std::vector<cvf::Vec3d>, std::vector<double> > RigWellPath::clippedPointSubset(double startMD, double endMD) const std::pair<std::vector<cvf::Vec3d>, std::vector<double> > RigWellPath::clippedPointSubset(double startMD, double endMD) const
{ {
std::pair<std::vector<cvf::Vec3d>, std::vector<double> > pointsAndMDs; std::pair<std::vector<cvf::Vec3d>, std::vector<double> > pointsAndMDs;
if (m_measuredDepths.empty()) return pointsAndMDs; if ( m_measuredDepths.empty() ) return pointsAndMDs;
if (startMD > endMD) return pointsAndMDs; if ( startMD > endMD ) return pointsAndMDs;
pointsAndMDs.first.push_back(interpolatedPointAlongWellPath(startMD)); pointsAndMDs.first.push_back(interpolatedPointAlongWellPath(startMD));
pointsAndMDs.second.push_back(startMD); pointsAndMDs.second.push_back(startMD);
for (size_t i = 0; i < m_measuredDepths.size(); ++i) for ( size_t i = 0; i < m_measuredDepths.size(); ++i )
{ {
double measuredDepth = m_measuredDepths[i]; double measuredDepth = m_measuredDepths[i];
if (measuredDepth > startMD && measuredDepth < endMD) if ( measuredDepth > startMD && measuredDepth < endMD )
{ {
pointsAndMDs.first.push_back(m_wellPathPoints[i]); pointsAndMDs.first.push_back(m_wellPathPoints[i]);
pointsAndMDs.second.push_back(measuredDepth); pointsAndMDs.second.push_back(measuredDepth);
@ -218,27 +219,27 @@ std::pair<std::vector<cvf::Vec3d>, std::vector<double> > RigWellPath::clippedPoi
std::vector<cvf::Vec3d> RigWellPath::wellPathPointsIncludingInterpolatedIntersectionPoint(double intersectionMeasuredDepth) const std::vector<cvf::Vec3d> RigWellPath::wellPathPointsIncludingInterpolatedIntersectionPoint(double intersectionMeasuredDepth) const
{ {
std::vector<cvf::Vec3d> points; std::vector<cvf::Vec3d> points;
if (m_measuredDepths.empty()) return points; if ( m_measuredDepths.empty() ) return points;
cvf::Vec3d interpolatedWellPathPoint = interpolatedPointAlongWellPath(intersectionMeasuredDepth); cvf::Vec3d interpolatedWellPathPoint = interpolatedPointAlongWellPath(intersectionMeasuredDepth);
for (size_t i = 0; i < m_measuredDepths.size() - 1; i++) for ( size_t i = 0; i < m_measuredDepths.size() - 1; i++ )
{ {
if (m_measuredDepths[i] == intersectionMeasuredDepth) if ( m_measuredDepths[i] == intersectionMeasuredDepth )
{ {
points.push_back(m_wellPathPoints[i]); points.push_back(m_wellPathPoints[i]);
} }
else if (m_measuredDepths[i] < intersectionMeasuredDepth) else if ( m_measuredDepths[i] < intersectionMeasuredDepth )
{ {
points.push_back(m_wellPathPoints[i]); points.push_back(m_wellPathPoints[i]);
if (m_measuredDepths[i + 1] > intersectionMeasuredDepth) if ( m_measuredDepths[i + 1] > intersectionMeasuredDepth )
{ {
points.push_back(interpolatedWellPathPoint); points.push_back(interpolatedWellPathPoint);
} }
} }
else if (m_measuredDepths[i] > intersectionMeasuredDepth) else if ( m_measuredDepths[i] > intersectionMeasuredDepth )
{ {
if (i == 0) if ( i == 0 )
{ {
points.push_back(interpolatedWellPathPoint); points.push_back(interpolatedWellPathPoint);
} }
@ -253,3 +254,88 @@ std::vector<cvf::Vec3d> RigWellPath::wellPathPointsIncludingInterpolatedIntersec
return points; return points;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigWellPath::isPolylineTouchingBBox(const std::vector<cvf::Vec3d> &polyLine,
const cvf::BoundingBox& caseBB)
{
for ( const cvf::Vec3d& point : polyLine )
{
if ( caseBB.contains(point) ) return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RigWellPath::clipPolylineStartAboveZ(const std::vector<cvf::Vec3d>& polyLine,
double maxZ,
double * horizontalLengthAlongWellToClipPoint)
{
CVF_ASSERT(horizontalLengthAlongWellToClipPoint != nullptr);
// Find first visible point, and accumulate distance along wellpath
*horizontalLengthAlongWellToClipPoint = 0.0;
size_t firstVisiblePointIndex = cvf::UNDEFINED_SIZE_T;
for ( size_t vxIdx = 0 ; vxIdx < polyLine.size(); ++vxIdx )
{
if ( polyLine[vxIdx].z() > maxZ )
{
if ( vxIdx > 0 )
{
cvf::Vec3d segment = polyLine[vxIdx] - polyLine[vxIdx-1];
segment[2] = 0.0;
*horizontalLengthAlongWellToClipPoint += segment.length();
}
}
else
{
firstVisiblePointIndex = vxIdx;
break;
}
}
// Clip line, and add vx to the start of the clipped result
std::vector<cvf::Vec3d> clippedPolyLine;
if ( firstVisiblePointIndex == cvf::UNDEFINED_SIZE_T )
{
return clippedPolyLine;
}
if ( firstVisiblePointIndex > 0 )
{
cvf::Plane topPlane;
topPlane.setFromPointAndNormal({ 0.0, 0.0, maxZ }, cvf::Vec3d::Z_AXIS);
cvf::Vec3d intersection;
if ( topPlane.intersect(polyLine[firstVisiblePointIndex-1],
polyLine[firstVisiblePointIndex],
&intersection) )
{
cvf::Vec3d segment = intersection - polyLine[firstVisiblePointIndex-1];
segment[2] = 0.0;
*horizontalLengthAlongWellToClipPoint += segment.length();
clippedPolyLine.push_back(intersection);
}
}
// Add the rest of the polyline
for ( size_t vxIdx = firstVisiblePointIndex; vxIdx < polyLine.size(); ++vxIdx )
{
clippedPolyLine.push_back(polyLine[vxIdx]);
}
return clippedPolyLine;
}

View File

@ -23,6 +23,11 @@
#include "cvfMath.h" #include "cvfMath.h"
#include "cvfVector3.h" #include "cvfVector3.h"
namespace cvf
{
class BoundingBox;
}
#include <vector> #include <vector>
@ -49,6 +54,12 @@ public:
std::vector<cvf::Vec3d> wellPathPointsIncludingInterpolatedIntersectionPoint(double intersectionMeasuredDepth) const; std::vector<cvf::Vec3d> wellPathPointsIncludingInterpolatedIntersectionPoint(double intersectionMeasuredDepth) const;
static bool isPolylineTouchingBBox(const std::vector<cvf::Vec3d> &polyLine,
const cvf::BoundingBox& caseBB);
static std::vector<cvf::Vec3d> clipPolylineStartAboveZ(const std::vector<cvf::Vec3d> &polyLine,
double maxZ,
double * horizontalLengthAlongWellToClipPoint);
private: private:
bool m_hasDatumElevation; bool m_hasDatumElevation;
double m_datumElevation; double m_datumElevation;

View File

@ -31,6 +31,7 @@
#include "RimGeoMechView.h" #include "RimGeoMechView.h"
#include "Rim2dIntersectionView.h" #include "Rim2dIntersectionView.h"
#include "RiuGeoMechXfTensorResultAccessor.h" #include "RiuGeoMechXfTensorResultAccessor.h"
#include "RivIntersectionPartMgr.h"