#3441 Valve visualisation in 3D view.

This commit is contained in:
Gaute Lindkvist 2018-10-10 16:57:43 +02:00
parent cfbe6a1a24
commit e7a39fb2f8
17 changed files with 590 additions and 149 deletions

View File

@ -397,6 +397,176 @@ cvf::ref<cvf::DrawableGeo> RivPipeGeometryGenerator::generateExtrudedCylinder(do
return geo;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivPipeGeometryGenerator::generateVariableRadiusTube(size_t crossSectionNodeCount,
const cvf::Vec3dArray* cylinderCenterCoords,
const std::vector<double>& radii)
{
const double epsilon = 1.0e-8;
CVF_ASSERT(cylinderCenterCoords != nullptr);
// Calculate first valid pipe direction, to be able to handle centerNodes in the same place
cvf::Vec3d lastValidPipeDirection = cvf::Vec3d::UNDEFINED;
for (size_t i = 0; i < cylinderCenterCoords->size() - 1; i++)
{
cvf::Vec3d candidateDir = (*cylinderCenterCoords)[i + 1] - (*cylinderCenterCoords)[i];
if (candidateDir.normalize())
{
lastValidPipeDirection = candidateDir;
break;
}
}
if (lastValidPipeDirection.isUndefined()) return nullptr; // The pipe coordinates are all the same point
cvf::Vec3d dir = (*cylinderCenterCoords)[1] - (*cylinderCenterCoords)[0];
if (!dir.normalize())
{
dir = lastValidPipeDirection;
}
cvf::Vec3d orient1 = dir.perpendicularVector();
orient1.normalize();
cvf::Vec3d orient2 = dir ^ orient1;
orient2.normalize();
std::vector<cvf::Vec3d> lastExtrudedNodes;
computeCircle(radii[0], crossSectionNodeCount, (*cylinderCenterCoords)[0], orient1, orient2, &lastExtrudedNodes);
std::vector<cvf::Vec3f> crossSectionVertices;
std::vector<cvf::Vec3f> cylinderSegmentNormals;
// Insert the first set of vertices
for (size_t i = 0; i < lastExtrudedNodes.size(); i++)
{
crossSectionVertices.push_back(cvf::Vec3f(lastExtrudedNodes[i]));
}
// Loop along the cylinder center coords and calculate the cross section vertexes in each center vertex
for (size_t ccIdx = 0; ccIdx < cylinderCenterCoords->size()-1; ccIdx++)
{
size_t nextCcIdx = ccIdx + 1;
// Calculate this and next pipe direction, and intersection plane
cvf::Vec3d firstCoord = (*cylinderCenterCoords)[ccIdx];
cvf::Vec3d secondCoord = (*cylinderCenterCoords)[nextCcIdx];
cvf::Vec3d nextDir = secondCoord - firstCoord;
if (!nextDir.normalize())
{
nextDir = lastValidPipeDirection;
}
else
{
lastValidPipeDirection = nextDir;
}
orient1 = nextDir.perpendicularVector().getNormalized();
orient2 = (nextDir ^ orient1).getNormalized();
std::vector<cvf::Vec3d> extrudedNodes;
computeCircle(radii[nextCcIdx], crossSectionNodeCount, (*cylinderCenterCoords)[nextCcIdx], orient1, orient2, &extrudedNodes);
// Insert the next set of vertices and calculate normals for segment
for (size_t i = 0; i < extrudedNodes.size(); i++)
{
cvf::Vec3f nextNodeAlongWellPath = cvf::Vec3f(extrudedNodes[i]);
cvf::Vec3f currentNode = cvf::Vec3f(lastExtrudedNodes[i]);
cvf::Vec3f wellDirectionDir = nextNodeAlongWellPath - currentNode;
if (!wellDirectionDir.normalize())
{
wellDirectionDir = cvf::Vec3f(lastValidPipeDirection);
}
cvf::Vec3f lastNodeAlongCircle;
cvf::Vec3f nextNodeAlongCircle;
if (i > 0)
{
lastNodeAlongCircle = cvf::Vec3f(lastExtrudedNodes[i - 1]);
}
else
{
lastNodeAlongCircle = cvf::Vec3f(lastExtrudedNodes.back());
}
if (i < extrudedNodes.size() - 1)
{
nextNodeAlongCircle = cvf::Vec3f(lastExtrudedNodes[i + 1]);
}
else
{
nextNodeAlongCircle = cvf::Vec3f(lastExtrudedNodes.front());
}
cvf::Vec3f circleDir = (nextNodeAlongCircle - lastNodeAlongCircle).getNormalized();
cvf::Vec3f segmentNormal = (wellDirectionDir ^ circleDir).getNormalized();
crossSectionVertices.push_back(cvf::Vec3f(nextNodeAlongWellPath));
cylinderSegmentNormals.push_back(segmentNormal);
}
lastExtrudedNodes = extrudedNodes;
}
size_t crossSectionCount = crossSectionVertices.size() / crossSectionNodeCount;
if (crossSectionCount < 2) return nullptr;
CVF_ASSERT(crossSectionVertices.size() - crossSectionNodeCount == cylinderSegmentNormals.size());
size_t segmentCount = crossSectionCount - 1;
size_t vertexCount = segmentCount * crossSectionNodeCount * 4;
cvf::ref<cvf::Vec3fArray> quadVertexArray = new cvf::Vec3fArray();
quadVertexArray->reserve(vertexCount);
cvf::ref<cvf::Vec3fArray> quadNormalArray = new cvf::Vec3fArray();
quadNormalArray->reserve(vertexCount);
size_t segmentIdx = 0;
for (segmentIdx = 0; segmentIdx < segmentCount; segmentIdx++)
{
for (size_t nodeIdx = 0; nodeIdx < crossSectionNodeCount - 1; nodeIdx++)
{
quadVertexArray->add(crossSectionVertices[((segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 0]);
quadVertexArray->add(crossSectionVertices[((segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 1]);
quadVertexArray->add(crossSectionVertices[((segmentIdx + 1) * crossSectionNodeCount) + nodeIdx + 1]);
quadVertexArray->add(crossSectionVertices[((segmentIdx + 1) * crossSectionNodeCount) + nodeIdx + 0]);
quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 0]);
quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 1]);
quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 1]);
quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 0]);
}
// Last quad closing the cylinder
quadVertexArray->add(crossSectionVertices[((segmentIdx + 0) * crossSectionNodeCount) + crossSectionNodeCount - 1]);
quadVertexArray->add(crossSectionVertices[((segmentIdx + 0) * crossSectionNodeCount) + 0]);
quadVertexArray->add(crossSectionVertices[((segmentIdx + 1) * crossSectionNodeCount) + 0]);
quadVertexArray->add(crossSectionVertices[((segmentIdx + 1) * crossSectionNodeCount) + crossSectionNodeCount - 1]);
quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + crossSectionNodeCount - 1]);
quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + 0]);
quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + 0]);
quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + crossSectionNodeCount - 1]);
}
CVF_ASSERT(vertexCount == quadVertexArray->size());
CVF_ASSERT(vertexCount == quadNormalArray->size());
cvf::ref<cvf::DrawableGeo> geo = new cvf::DrawableGeo;
geo->setFromQuadVertexArray(quadVertexArray.p());
geo->setNormalArray(quadNormalArray.p());
return geo;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -647,3 +817,46 @@ void RivPipeGeometryGenerator::cylinderWithCenterLineParts(cvf::Collection<cvf::
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivPipeGeometryGenerator::tubeWithCenterLinePartsAndVariableWidth(cvf::Collection<cvf::Part>* destinationParts,
const std::vector<cvf::Vec3d>& centerCoords,
const std::vector<double>& radii,
const cvf::Color3f& color)
{
setCrossSectionVertexCount(12);
cvf::ref<cvf::Vec3dArray> activeCoords = new cvf::Vec3dArray(centerCoords);
setPipeCenterCoords(activeCoords.p());
cvf::ref<cvf::DrawableGeo> surfaceGeo = generateVariableRadiusTube(m_crossSectionNodeCount, activeCoords.p(), radii);
if (surfaceGeo.notNull())
{
cvf::Part* part = new cvf::Part;
part->setDrawable(surfaceGeo.p());
caf::SurfaceEffectGenerator surfaceGen(cvf::Color4f(color), caf::PO_1);
cvf::ref<cvf::Effect> eff = surfaceGen.generateCachedEffect();
part->setEffect(eff.p());
destinationParts->push_back(part);
}
cvf::ref<cvf::DrawableGeo> centerLineGeo = createCenterLine();
if (centerLineGeo.notNull())
{
cvf::Part* part = new cvf::Part;
part->setDrawable(centerLineGeo.p());
caf::SurfaceEffectGenerator surfaceGen(cvf::Color4f(color), caf::PO_1);
cvf::ref<cvf::Effect> eff = surfaceGen.generateCachedEffect();
part->setEffect(eff.p());
destinationParts->push_back(part);
}
}

View File

@ -64,7 +64,16 @@ public:
void setFirstVisibleSegmentIndex(size_t segmentIndex);
size_t segmentIndexFromTriangleIndex(size_t triangleIndex) const;
void cylinderWithCenterLineParts(cvf::Collection<cvf::Part>* destinationParts, const std::vector<cvf::Vec3d>& centerCoords, const cvf::Color3f& color, double radius);
void cylinderWithCenterLineParts(cvf::Collection<cvf::Part>* destinationParts,
const std::vector<cvf::Vec3d>& centerCoords,
const cvf::Color3f& color,
double radius);
void tubeWithCenterLinePartsAndVariableWidth(cvf::Collection<cvf::Part>* destinationParts,
const std::vector<cvf::Vec3d>& centerCoords,
const std::vector<double>& radii,
const cvf::Color3f& color);
private:
void clearComputedData();
void updateFilteredPipeCenterCoords();
@ -75,6 +84,7 @@ private:
static cvf::ref<cvf::DrawableGeo> generateLine(const cvf::Vec3dArray* coords);
static cvf::ref<cvf::DrawableGeo> generateExtrudedCylinder(double radius, size_t crossSectionNodeCount,const cvf::Vec3dArray* cylinderCenterCoords);
static cvf::ref<cvf::DrawableGeo> generateVariableRadiusTube(size_t crossSectionNodeCount, const cvf::Vec3dArray* cylinderCenterCoords, const std::vector<double>& radii);
static void computeExtrudedCoordsAndNormals(cvf::Vec3d intersectionCoord,
cvf::Vec3d intersectionPlaneNormal,

View File

@ -38,7 +38,10 @@
#include "RimPerforationCollection.h"
#include "RimPerforationInterval.h"
#include "RimWellPath.h"
#include "RimWellPathAttribute.h"
#include "RimWellPathAttributeCollection.h"
#include "RimWellPathCollection.h"
#include "RimWellPathValve.h"
#include "RimWellPathFractureCollection.h"
#include "RimWellPathFracture.h"
@ -159,6 +162,52 @@ void RivWellPathPartMgr::appendFishboneSubsPartsToModel(cvf::ModelBasicList* mod
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivWellPathPartMgr::appendCasingShoesToModel(cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform,
double characteristicCellSize)
{
if (!m_rimWellPath) return;
RivPipeGeometryGenerator geoGenerator;
std::vector<RimWellPathAttribute*> attributes = m_rimWellPath->attributeCollection()->attributes();
for (RimWellPathAttribute* attribute : attributes)
{
if (attribute->componentType() == RiaDefines::CASING)
{
double wellPathRadius = this->wellPathRadius(characteristicCellSize, this->wellPathCollection());
double endMD = attribute->endMD();
double shoeStartMD = endMD - 2.5;
std::vector<cvf::Vec3d> displayCoords;
displayCoords.push_back(displayCoordTransform->transformToDisplayCoord(m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(shoeStartMD)));
displayCoords.push_back(displayCoordTransform->transformToDisplayCoord(m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(endMD)));
displayCoords.push_back(displayCoordTransform->transformToDisplayCoord(m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(endMD)));
std::vector<double> radii;
radii.push_back(wellPathRadius);
radii.push_back(wellPathRadius * 2.0);
radii.push_back(wellPathRadius * 1.1);
cvf::ref<RivObjectSourceInfo> objectSourceInfo = new RivObjectSourceInfo(attribute);
cvf::Collection<cvf::Part> parts;
geoGenerator.tubeWithCenterLinePartsAndVariableWidth(&parts, displayCoords, radii, attribute->defaultComponentColor());
for (auto part : parts)
{
part->setSourceInfo(objectSourceInfo.p());
model->addPart(part.p());
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -282,15 +331,95 @@ void RivWellPathPartMgr::appendPerforationsToModel(cvf::ModelBasicList* model,
perfIntervalCLDiplayCS.push_back( displayCoordTransform->transformToDisplayCoord(point));
}
}
cvf::ref<RivObjectSourceInfo> objectSourceInfo = new RivObjectSourceInfo(perforation);
cvf::Collection<cvf::Part> parts;
geoGenerator.cylinderWithCenterLineParts(&parts, perfIntervalCLDiplayCS, cvf::Color3f::GREEN, perforationRadius);
for (auto part : parts)
{
part->setSourceInfo(objectSourceInfo.p());
model->addPart(part.p());
cvf::ref<RivObjectSourceInfo> objectSourceInfo = new RivObjectSourceInfo(perforation);
cvf::Collection<cvf::Part> parts;
geoGenerator.cylinderWithCenterLineParts(&parts, perfIntervalCLDiplayCS, cvf::Color3f::GREEN, perforationRadius);
for (auto part : parts)
{
part->setSourceInfo(objectSourceInfo.p());
model->addPart(part.p());
}
}
appendPerforationValvesToModel(model, perforation, wellPathRadius, displayCoordTransform, geoGenerator);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivWellPathPartMgr::appendPerforationValvesToModel(cvf::ModelBasicList* model, RimPerforationInterval* perforation, double wellPathRadius, const caf::DisplayCoordTransform* displayCoordTransform, RivPipeGeometryGenerator &geoGenerator)
{
// Valves
{
for (RimWellPathValve* valve : perforation->valves())
{
if (!valve->isChecked()) continue;
std::vector<double> measuredDepthsRelativeToStartMD;
std::vector<double> radii;
cvf::Color3f valveColor = valve->defaultComponentColor();
if (valve->componentType() == RiaDefines::ICV)
{
measuredDepthsRelativeToStartMD = { 0.0, 1.0, 1.5, 4.0, 5.0, 5.5, 8.0, 9.0 };
radii = { wellPathRadius, wellPathRadius * 1.8, wellPathRadius * 2.0,
wellPathRadius * 2.0, wellPathRadius * 1.8,
wellPathRadius * 1.7, wellPathRadius * 1.7, wellPathRadius };
}
else if (valve->componentType() == RiaDefines::ICD || valve->componentType() == RiaDefines::AICD)
{
int size = 16;
measuredDepthsRelativeToStartMD.resize(size);
radii.resize(size);
for (int i = 0; i < size; i += 2)
{
measuredDepthsRelativeToStartMD[i] = double(i / 2);
measuredDepthsRelativeToStartMD[i + 1] = double(i / 2 + 0.5);
}
radii[0] = wellPathRadius;
bool inner = false;
int nInners = 0;
for (size_t i = 1; i < size; i += 2)
{
if (inner && valve->componentType() == RiaDefines::AICD && nInners > 0)
{
radii[i + 1] = radii[i] = wellPathRadius * 1.7;
nInners = 0;
}
else if (inner)
{
radii[i + 1] = radii[i] = wellPathRadius * 1.9;
nInners++;
}
else
{
radii[i + 1] = radii[i] = wellPathRadius * 2.0;
}
inner = !inner;
}
radii[size - 1] = wellPathRadius;
}
double startMD = valve->startMD();
std::vector<cvf::Vec3d> displayCoords;
for (double mdRelativeToStart : measuredDepthsRelativeToStartMD)
{
displayCoords.push_back(displayCoordTransform->transformToDisplayCoord(
m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(mdRelativeToStart + startMD)));
}
cvf::ref<RivObjectSourceInfo> objectSourceInfo = new RivObjectSourceInfo(valve);
cvf::Collection<cvf::Part> parts;
geoGenerator.tubeWithCenterLinePartsAndVariableWidth(&parts, displayCoords, radii, valveColor);
for (auto part : parts)
{
part->setSourceInfo(objectSourceInfo.p());
model->addPart(part.p());
}
}
}
}
@ -502,6 +631,7 @@ void RivWellPathPartMgr::appendStaticGeometryPartsToModel(cvf::ModelBasicList*
appendFishboneSubsPartsToModel(model, displayCoordTransform, characteristicCellSize);
appendImportedFishbonesToModel(model, displayCoordTransform, characteristicCellSize);
appendCasingShoesToModel(model, displayCoordTransform, characteristicCellSize);
RimGridView* gridView = dynamic_cast<RimGridView*>(m_rimView.p());
if (!gridView) return;

View File

@ -43,6 +43,7 @@ class RivPipeGeometryGenerator;
class RimProject;
class RimWellPath;
class RivFishbonesSubsPartMgr;
class RimPerforationInterval;
class RimWellPathCollection;
class Rim3dView;
class Riv3dWellLogPlanePartMgr;
@ -88,6 +89,10 @@ private:
const caf::DisplayCoordTransform* displayCoordTransform,
double characteristicCellSize);
void appendCasingShoesToModel(cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform,
double characteristicCellSize);
void appendImportedFishbonesToModel(cvf::ModelBasicList* model,
const caf::DisplayCoordTransform* displayCoordTransform,
double characteristicCellSize);
@ -98,6 +103,12 @@ private:
double characteristicCellSize,
bool doFlatten);
void appendPerforationValvesToModel(cvf::ModelBasicList* model,
RimPerforationInterval* perforation,
double wellPathRadius,
const caf::DisplayCoordTransform* displayCoordTransform,
RivPipeGeometryGenerator& geoGenerator);
void appendVirtualTransmissibilitiesToModel(cvf::ModelBasicList* model,
size_t timeStepIndex,
const caf::DisplayCoordTransform* displayCoordTransform,

View File

@ -408,6 +408,30 @@ RiaDefines::WellPathComponentType RimFishbonesMultipleSubs::componentType() cons
return RiaDefines::FISHBONES;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFishbonesMultipleSubs::componentLabel() const
{
return generatedName();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFishbonesMultipleSubs::componentTypeLabel() const
{
return "Fishbones";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3f RimFishbonesMultipleSubs::defaultComponentColor() const
{
return fishbonesColor();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -436,22 +460,6 @@ double RimFishbonesMultipleSubs::endMD() const
return measuredDepth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFishbonesMultipleSubs::componentLabel() const
{
return generatedName();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFishbonesMultipleSubs::componentTypeLabel() const
{
return "Fishbones";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -107,11 +107,11 @@ public:
// Overrides from RimWellPathCompletionsInterface
RiaDefines::WellPathComponentType componentType() const override;
double startMD() const override;
double endMD() const override;
QString componentLabel() const override;
QString componentTypeLabel() const override;
cvf::Color3f defaultComponentColor() const override;
double startMD() const override;
double endMD() const override;
public:
caf::PdmField<cvf::Color3f> fishbonesColor;

View File

@ -293,6 +293,30 @@ RiaDefines::WellPathComponentType RimFracture::componentType() const
return RiaDefines::FRACTURE;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFracture::componentLabel() const
{
return name();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFracture::componentTypeLabel() const
{
return "Fracture";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3f RimFracture::defaultComponentColor() const
{
return cvf::Color3f(cvf::Color3::ORANGE_RED);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -323,22 +347,6 @@ double RimFracture::endMD() const
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFracture::componentLabel() const
{
return name();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFracture::componentTypeLabel() const
{
return "Fracture";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -130,10 +130,11 @@ public:
// RimWellPathCompletionsInterface overrides.
RiaDefines::WellPathComponentType componentType() const override;
double startMD() const override;
double endMD() const override;
QString componentLabel() const override;
QString componentTypeLabel() const override;
cvf::Color3f defaultComponentColor() const override;
double startMD() const override;
double endMD() const override;
protected:
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override;

View File

@ -238,22 +238,6 @@ RiaDefines::WellPathComponentType RimPerforationInterval::componentType() const
return RiaDefines::PERFORATION_INTERVAL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimPerforationInterval::startMD() const
{
return m_startMD();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimPerforationInterval::endMD() const
{
return m_endMD();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -270,6 +254,30 @@ QString RimPerforationInterval::componentTypeLabel() const
return "Perforations";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3f RimPerforationInterval::defaultComponentColor() const
{
return cvf::Color3f(cvf::Color3::GREEN);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimPerforationInterval::startMD() const
{
return m_startMD();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimPerforationInterval::endMD() const
{
return m_endMD();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -68,10 +68,11 @@ public:
// RimWellPathCompletionInterface overrides
RiaDefines::WellPathComponentType componentType() const override;
double startMD() const;
double endMD() const;
QString componentLabel() const override;
QString componentTypeLabel() const override;
cvf::Color3f defaultComponentColor() const override;
double startMD() const;
double endMD() const;
protected:
virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;

View File

@ -20,6 +20,9 @@
#include "RiaDefines.h"
#include "cvfBase.h"
#include "cvfColor3.h"
//==================================================================================================
// Interface implemented by all well path construction components and completions
//
@ -29,10 +32,11 @@ class RimWellPathComponentInterface
{
public:
virtual RiaDefines::WellPathComponentType componentType() const = 0;
virtual double startMD() const = 0;
virtual double endMD() const = 0;
virtual QString componentLabel() const = 0;
virtual QString componentTypeLabel() const = 0;
virtual cvf::Color3f defaultComponentColor() const = 0;
virtual double startMD() const = 0;
virtual double endMD() const = 0;
};

View File

@ -68,22 +68,6 @@ RiaDefines::WellPathComponentType RimWellPathValve::componentType() const
return m_type();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellPathValve::startMD() const
{
return m_measuredDepth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellPathValve::endMD() const
{
return m_measuredDepth + 0.5;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -100,6 +84,42 @@ QString RimWellPathValve::componentTypeLabel() const
return m_type().uiText();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3f RimWellPathValve::defaultComponentColor() const
{
switch (m_type())
{
case RiaDefines::ICD:
return cvf::Color3f(cvf::Color3::DARK_BLUE);
case RiaDefines::AICD:
return cvf::Color3f(cvf::Color3::BROWN);
case RiaDefines::ICV:
return cvf::Color3f(cvf::Color3::DARK_VIOLET);
default:
break;
}
CVF_ASSERT(false);
return cvf::Color3f(cvf::Color3::BLACK);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellPathValve::startMD() const
{
return m_measuredDepth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellPathValve::endMD() const
{
return m_measuredDepth + 0.5;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -23,7 +23,6 @@
#include "cafPdmObject.h"
#include "cafAppEnum.h"
#include "cvfBase.h"
#include "cafPdmField.h"
#include <QList>
@ -44,11 +43,12 @@ public:
// Overrides from RimWellPathCompletionInterface
RiaDefines::WellPathComponentType componentType() const override;
QString componentLabel() const override;
QString componentTypeLabel() const override;
cvf::Color3f defaultComponentColor() const override;
double startMD() const override;
double endMD() const override;
QString componentLabel() const override;
QString componentTypeLabel() const override;
private:
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;

View File

@ -18,6 +18,8 @@
#include "RimWellPathAttribute.h"
#include "RigWellPath.h"
#include "RimProject.h"
#include "RimWellPathAttributeCollection.h"
#include "RimWellPath.h"
@ -96,22 +98,6 @@ RiaDefines::WellPathComponentType RimWellPathAttribute::componentType() const
return m_type();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellPathAttribute::startMD() const
{
return m_startMD();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellPathAttribute::endMD() const
{
return m_endMD();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -133,6 +119,42 @@ QString RimWellPathAttribute::componentTypeLabel() const
return m_type().uiText();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3f RimWellPathAttribute::defaultComponentColor() const
{
switch (m_type())
{
case RiaDefines::CASING:
return cvf::Color3::FOREST_GREEN;
case RiaDefines::LINER:
return cvf::Color3::OLIVE;
case RiaDefines::PACKER:
return cvf::Color3::GRAY;
default:
break;
}
CVF_ASSERT(false);
return cvf::Color3f(cvf::Color3::BLACK);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellPathAttribute::startMD() const
{
return m_startMD();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellPathAttribute::endMD() const
{
return m_endMD();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -213,6 +235,11 @@ void RimWellPathAttribute::fieldChangedByUi(const caf::PdmFieldHandle* changedFi
this->firstAncestorOrThisOfTypeAsserted(collection);
collection->updateAllReferringTracks();
}
{
RimProject* proj;
this->firstAncestorOrThisOfTypeAsserted(proj);
proj->reloadCompletionTypeResultsInAllViews();
}
}
//--------------------------------------------------------------------------------------------------

View File

@ -47,11 +47,12 @@ public:
// Overrides from RimWellPathCompletionInterface
RiaDefines::WellPathComponentType componentType() const override;
double startMD() const override;
double endMD() const override;
QString componentLabel() const override;
QString componentTypeLabel() const override;
cvf::Color3f defaultComponentColor() const override;
double startMD() const override;
double endMD() const override;
private:
bool isDiameterSupported() const;
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;

View File

@ -45,6 +45,7 @@
RiuWellPathComponentPlotItem::RiuWellPathComponentPlotItem(const RimWellPath* wellPath)
: m_wellPath(wellPath)
, m_componentType(RiaDefines::WELL_PATH)
, m_baseColor(cvf::Color3f(cvf::Color3::LIGHT_GRAY))
, m_depthType(RimWellLogPlot::MEASURED_DEPTH)
, m_showLabel(false)
{
@ -60,18 +61,19 @@ RiuWellPathComponentPlotItem::RiuWellPathComponentPlotItem(const RimWellPath* we
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellPathComponentPlotItem::RiuWellPathComponentPlotItem(const RimWellPath* wellPath, const RimWellPathComponentInterface* completion)
RiuWellPathComponentPlotItem::RiuWellPathComponentPlotItem(const RimWellPath* wellPath, const RimWellPathComponentInterface* component)
: m_wellPath(wellPath)
, m_depthType(RimWellLogPlot::MEASURED_DEPTH)
, m_showLabel(false)
{
CVF_ASSERT(wellPath && completion);
CVF_ASSERT(wellPath && component);
m_componentType = completion->componentType();
m_startMD = completion->startMD();
m_endMD = completion->endMD();
m_label = completion->componentLabel();
m_legendTitle = completion->componentTypeLabel();
m_componentType = component->componentType();
m_label = component->componentLabel();
m_legendTitle = component->componentTypeLabel();
m_baseColor = component->defaultComponentColor();
m_startMD = component->startMD();
m_endMD = component->endMD();
}
//--------------------------------------------------------------------------------------------------
@ -106,7 +108,7 @@ void RiuWellPathComponentPlotItem::loadDataAndUpdate(bool updateParentPlot)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaDefines::WellPathComponentType RiuWellPathComponentPlotItem::completionType() const
RiaDefines::WellPathComponentType RiuWellPathComponentPlotItem::componentType() const
{
return m_componentType;
}
@ -120,8 +122,6 @@ void RiuWellPathComponentPlotItem::onLoadDataAndUpdate(bool updateParentPlot)
std::tie(startDepth, endDepth) = depthsOfDepthType();
double midDepth = 0.5 * (startDepth + endDepth);
float completionAlpha = 0.9f;
if (m_componentType == RiaDefines::WELL_PATH)
{
addColumnFeature(-0.25, 0.25, startDepth, endDepth, componentColor());
@ -141,8 +141,8 @@ void RiuWellPathComponentPlotItem::onLoadDataAndUpdate(bool updateParentPlot)
}
else if (m_componentType == RiaDefines::PERFORATION_INTERVAL)
{
addColumnFeature(-0.75, -0.25, startDepth, endDepth, componentColor(completionAlpha), Qt::Dense6Pattern);
addColumnFeature(0.25, 0.75, startDepth, endDepth, componentColor(completionAlpha), Qt::Dense6Pattern);
addColumnFeature(-0.75, -0.25, startDepth, endDepth, componentColor(), Qt::Dense6Pattern);
addColumnFeature(0.25, 0.75, startDepth, endDepth, componentColor(), Qt::Dense6Pattern);
// Empirically a spacing of around 30 in depth between symbols looks good in the most relevant zoom levels.
const double markerSpacing = 30;
const int markerSize = 6;
@ -165,16 +165,16 @@ void RiuWellPathComponentPlotItem::onLoadDataAndUpdate(bool updateParentPlot)
}
else if (m_componentType == RiaDefines::FISHBONES)
{
addColumnFeature(-0.75, -0.25, startDepth, endDepth, componentColor(completionAlpha), Qt::BDiagPattern);
addColumnFeature(0.25, 0.75, startDepth, endDepth, componentColor(completionAlpha), Qt::FDiagPattern);
addColumnFeature(-0.75, -0.25, startDepth, endDepth, componentColor(), Qt::BDiagPattern);
addColumnFeature(0.25, 0.75, startDepth, endDepth, componentColor(), Qt::FDiagPattern);
addMarker(0.75, midDepth, 10, RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, componentColor(0.0), label());
}
else if (m_componentType == RiaDefines::FRACTURE)
{
addColumnFeature(-0.75, -0.25, startDepth, endDepth, componentColor(completionAlpha), Qt::SolidPattern);
addColumnFeature(0.25, 0.75, startDepth, endDepth, componentColor(completionAlpha), Qt::SolidPattern);
addMarker(0.75, startDepth, 10, RiuQwtSymbol::SYMBOL_NONE, componentColor(completionAlpha), "", Qt::AlignTop | Qt::AlignRight, Qt::Horizontal, true);
addMarker(0.75, endDepth, 10, RiuQwtSymbol::SYMBOL_NONE, componentColor(completionAlpha), "", Qt::AlignTop | Qt::AlignRight, Qt::Horizontal, true);
addColumnFeature(-0.75, -0.25, startDepth, endDepth, componentColor(), Qt::SolidPattern);
addColumnFeature(0.25, 0.75, startDepth, endDepth, componentColor(), Qt::SolidPattern);
addMarker(0.75, startDepth, 10, RiuQwtSymbol::SYMBOL_NONE, componentColor(), "", Qt::AlignTop | Qt::AlignRight, Qt::Horizontal, true);
addMarker(0.75, endDepth, 10, RiuQwtSymbol::SYMBOL_NONE, componentColor(), "", Qt::AlignTop | Qt::AlignRight, Qt::Horizontal, true);
addMarker(0.75, startDepth, 1, RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, cvf::Color4f(cvf::Color3::ORANGE_RED, 0.0f), label(), Qt::AlignTop | Qt::AlignRight);
}
else if (m_componentType == RiaDefines::ICD)
@ -287,25 +287,36 @@ void RiuWellPathComponentPlotItem::addColumnFeature(double startX,
double endDepth,
cvf::Color4f baseColor,
Qt::BrushStyle brushStyle /*= Qt::SolidPattern*/)
{
QwtPlotItem* backgroundShape = createColumnShape(startX, endX, startDepth, endDepth, baseColor, Qt::SolidPattern);
m_combinedComponentGroup.addPlotItem(backgroundShape);
if (endX >= 0.0)
{
QwtPlotItem* legendShape = createColumnShape(0.0, 16.0, 0.0, 16.0, baseColor, Qt::SolidPattern);
m_combinedComponentGroup.addLegendItem(legendShape);
}
{
if (brushStyle != Qt::SolidPattern)
{
// If we're doing a special pattern, draw the pattern in black over the existing pattern
// If we're doing a special pattern, draw the background in white first over the existing pattern
cvf::Color4f semiTransparentWhite(cvf::Color3f(cvf::Color3::WHITE), 0.9f);
QwtPlotItem* backgroundShape = createColumnShape(startX, endX, startDepth, endDepth, semiTransparentWhite, Qt::SolidPattern);
m_combinedComponentGroup.addPlotItem(backgroundShape);
QwtPlotItem* patternShape = createColumnShape(startX, endX, startDepth, endDepth, cvf::Color4f(cvf::Color3::BLACK), brushStyle);
m_combinedComponentGroup.addPlotItem(patternShape);
if (endX >= 0.0)
{
QwtPlotItem* legendBGShape = createColumnShape(0.0, 16.0, 0.0, 16.0, semiTransparentWhite, Qt::SolidPattern);
m_combinedComponentGroup.addLegendItem(legendBGShape);
QwtPlotItem* legendShape = createColumnShape(0.0, 16.0, 0.0, 16.0, cvf::Color4f(cvf::Color3::BLACK), brushStyle);
m_combinedComponentGroup.addLegendItem(legendShape);
}
}
else
{
QwtPlotItem* backgroundShape = createColumnShape(startX, endX, startDepth, endDepth, baseColor, Qt::SolidPattern);
m_combinedComponentGroup.addPlotItem(backgroundShape);
if (endX >= 0.0)
{
QwtPlotItem* legendShape = createColumnShape(0.0, 16.0, 0.0, 16.0, baseColor, Qt::SolidPattern);
m_combinedComponentGroup.addLegendItem(legendShape);
}
}
}
//--------------------------------------------------------------------------------------------------
@ -340,20 +351,7 @@ QwtPlotItem* RiuWellPathComponentPlotItem::createColumnShape(double star
//--------------------------------------------------------------------------------------------------
cvf::Color4f RiuWellPathComponentPlotItem::componentColor(float alpha /*= 1.0*/) const
{
const std::map<RiaDefines::WellPathComponentType, cvf::Color3::ColorIdent> colors
= {
{RiaDefines::WELL_PATH, cvf::Color3::LIGHT_GRAY},
{RiaDefines::CASING, cvf::Color3::SEA_GREEN},
{RiaDefines::LINER, cvf::Color3::OLIVE},
{RiaDefines::PACKER, cvf::Color3::GRAY},
{RiaDefines::PERFORATION_INTERVAL, cvf::Color3::WHITE},
{RiaDefines::FISHBONES, cvf::Color3::WHITE},
{RiaDefines::FRACTURE, cvf::Color3::ORANGE_RED},
{RiaDefines::ICD, cvf::Color3::DARK_BLUE},
{RiaDefines::AICD, cvf::Color3::BROWN},
{RiaDefines::ICV, cvf::Color3::DARK_VIOLET}
};
return cvf::Color4f(cvf::Color3f(colors.at(m_componentType)), alpha);
return cvf::Color4f(m_baseColor, alpha);
}
//--------------------------------------------------------------------------------------------------

View File

@ -52,8 +52,8 @@ class RiuWellPathComponentPlotItem
public:
RiuWellPathComponentPlotItem(const RimWellPath* wellPath);
RiuWellPathComponentPlotItem(const RimWellPath* wellPath,
const RimWellPathComponentInterface* completion);
RiuWellPathComponentPlotItem(const RimWellPath* wellPath,
const RimWellPathComponentInterface* completion);
~RiuWellPathComponentPlotItem();
@ -62,7 +62,7 @@ public:
void loadDataAndUpdate(bool updateParentPlot);
RiaDefines::WellPathComponentType completionType() const;
RiaDefines::WellPathComponentType componentType() const;
bool xValueRange(double* minimumValue, double* maximumValue) const;
bool yValueRange(double* minimumValue, double* maximumValue) const;
@ -126,6 +126,7 @@ private:
double m_endMD;
QString m_label;
QString m_legendTitle;
cvf::Color3f m_baseColor;
RimWellLogPlot::DepthTypeEnum m_depthType;
QPointer<QwtPlot> m_parentQwtPlot;