mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
3D Well Log Curves (#2671): Split normals, border and surface into several drawables.
* Also create a closed LINES_LOOP out of the mesh border. * This will facilitate using different effects on the different parts. i.e. solid border and white surface background.
This commit is contained in:
parent
6e0b7e2305
commit
e8b006d068
@ -25,10 +25,14 @@
|
|||||||
#include "RigWellPathGeometryTools.h"
|
#include "RigWellPathGeometryTools.h"
|
||||||
|
|
||||||
#include "cafDisplayCoordTransform.h"
|
#include "cafDisplayCoordTransform.h"
|
||||||
|
#include "cvfObject.h"
|
||||||
|
#include "cvfDrawableGeo.h"
|
||||||
#include "cvfPrimitiveSetIndexedUInt.h"
|
#include "cvfPrimitiveSetIndexedUInt.h"
|
||||||
|
|
||||||
#include "cvfBoundingBox.h"
|
#include "cvfBoundingBox.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -40,7 +44,8 @@ Riv3dWellLogGridGeometryGenerator::Riv3dWellLogGridGeometryGenerator(RimWellPath
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
cvf::ref<cvf::DrawableGeo> Riv3dWellLogGridGeometryGenerator::createGrid(const caf::DisplayCoordTransform* displayCoordTransform,
|
std::map< Riv3dWellLogGridGeometryGenerator::DrawableId, cvf::ref<cvf::DrawableGeo> >
|
||||||
|
Riv3dWellLogGridGeometryGenerator::createGrid(const caf::DisplayCoordTransform* displayCoordTransform,
|
||||||
const cvf::BoundingBox& wellPathClipBoundingBox,
|
const cvf::BoundingBox& wellPathClipBoundingBox,
|
||||||
double planeAngle,
|
double planeAngle,
|
||||||
double planeOffsetFromWellPathCenter,
|
double planeOffsetFromWellPathCenter,
|
||||||
@ -49,14 +54,25 @@ cvf::ref<cvf::DrawableGeo> Riv3dWellLogGridGeometryGenerator::createGrid(const c
|
|||||||
{
|
{
|
||||||
CVF_ASSERT(gridIntervalSize > 0);
|
CVF_ASSERT(gridIntervalSize > 0);
|
||||||
|
|
||||||
if (!wellPathGeometry()) return nullptr;
|
if (!wellPathGeometry() || wellPathGeometry()->m_measuredDepths.empty())
|
||||||
if (!wellPathClipBoundingBox.isValid()) return nullptr;
|
{
|
||||||
|
return std::map< DrawableId, cvf::ref<cvf::DrawableGeo> >();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wellPathClipBoundingBox.isValid())
|
||||||
|
{
|
||||||
|
return std::map< DrawableId, cvf::ref<cvf::DrawableGeo> >();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
RimWellPathCollection* wellPathCollection = nullptr;
|
RimWellPathCollection* wellPathCollection = nullptr;
|
||||||
m_wellPath->firstAncestorOrThisOfTypeAsserted(wellPathCollection);
|
m_wellPath->firstAncestorOrThisOfTypeAsserted(wellPathCollection);
|
||||||
|
|
||||||
std::vector<cvf::Vec3d> wellPathPoints = wellPathGeometry()->m_wellPathPoints;
|
std::vector<cvf::Vec3d> wellPathPoints = wellPathGeometry()->m_wellPathPoints;
|
||||||
if (wellPathPoints.empty()) return nullptr;
|
if (wellPathPoints.empty())
|
||||||
|
{
|
||||||
|
return std::map< DrawableId, cvf::ref<cvf::DrawableGeo> >();
|
||||||
|
}
|
||||||
|
|
||||||
size_t originalWellPathSize = wellPathPoints.size();
|
size_t originalWellPathSize = wellPathPoints.size();
|
||||||
|
|
||||||
@ -68,12 +84,16 @@ cvf::ref<cvf::DrawableGeo> Riv3dWellLogGridGeometryGenerator::createGrid(const c
|
|||||||
wellPathPoints = RigWellPath::clipPolylineStartAboveZ(
|
wellPathPoints = RigWellPath::clipPolylineStartAboveZ(
|
||||||
wellPathPoints, maxZClipHeight, &horizontalLengthAlongWellToClipPoint, &indexToFirstVisibleSegment);
|
wellPathPoints, maxZClipHeight, &horizontalLengthAlongWellToClipPoint, &indexToFirstVisibleSegment);
|
||||||
}
|
}
|
||||||
if (wellPathPoints.empty()) return nullptr;
|
|
||||||
|
if (wellPathPoints.empty())
|
||||||
|
{
|
||||||
|
return std::map< DrawableId, cvf::ref<cvf::DrawableGeo> >();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map< DrawableId, cvf::ref<cvf::DrawableGeo> > drawables;
|
||||||
|
|
||||||
std::vector<cvf::Vec3d> gridPoints;
|
std::vector<cvf::Vec3d> gridPoints;
|
||||||
|
|
||||||
if (wellPathGeometry()->m_measuredDepths.empty()) return nullptr;
|
|
||||||
|
|
||||||
size_t newStartIndex = originalWellPathSize - wellPathPoints.size();
|
size_t newStartIndex = originalWellPathSize - wellPathPoints.size();
|
||||||
double firstMd = wellPathGeometry()->m_measuredDepths.at(newStartIndex);
|
double firstMd = wellPathGeometry()->m_measuredDepths.at(newStartIndex);
|
||||||
double lastMd = wellPathGeometry()->m_measuredDepths.back();
|
double lastMd = wellPathGeometry()->m_measuredDepths.back();
|
||||||
@ -92,18 +112,64 @@ cvf::ref<cvf::DrawableGeo> Riv3dWellLogGridGeometryGenerator::createGrid(const c
|
|||||||
RigWellPathGeometryTools::calculatePairsOfClosestSamplingPointsAlongWellPath(wellPathGeometry(), gridPoints, &closestPoints);
|
RigWellPathGeometryTools::calculatePairsOfClosestSamplingPointsAlongWellPath(wellPathGeometry(), gridPoints, &closestPoints);
|
||||||
|
|
||||||
pointNormals = RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle, closestPoints, RigWellPathGeometryTools::LINE_SEGMENTS);
|
pointNormals = RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle, closestPoints, RigWellPathGeometryTools::LINE_SEGMENTS);
|
||||||
if (pointNormals.size() != gridPoints.size()) return nullptr;
|
if (pointNormals.size() != gridPoints.size())
|
||||||
|
{
|
||||||
|
return std::map< DrawableId, cvf::ref<cvf::DrawableGeo> >();
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculateLineSegmentNormals returns normals for the whole well path. Erase the part which is clipped off
|
||||||
|
std::vector<cvf::Vec3d> wellPathSegmentNormals =
|
||||||
|
RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle, wellPathGeometry()->m_wellPathPoints, RigWellPathGeometryTools::POLYLINE);
|
||||||
|
wellPathSegmentNormals.erase(wellPathSegmentNormals.begin(), wellPathSegmentNormals.end() - wellPathPoints.size());
|
||||||
|
|
||||||
|
{
|
||||||
std::vector<cvf::Vec3f> vertices;
|
std::vector<cvf::Vec3f> vertices;
|
||||||
vertices.reserve(gridPoints.size() * 2);
|
vertices.reserve(gridPoints.size());
|
||||||
|
|
||||||
std::vector<cvf::uint> indices;
|
std::vector<cvf::uint> indices;
|
||||||
indices.reserve(gridPoints.size() * 2);
|
indices.reserve(gridPoints.size());
|
||||||
|
|
||||||
cvf::uint indexCounter = 0;
|
cvf::uint indexCounter = 0;
|
||||||
|
// Line along and close to well
|
||||||
|
for (size_t i = 0; i < wellPathPoints.size(); i++)
|
||||||
|
{
|
||||||
|
vertices.push_back(cvf::Vec3f(displayCoordTransform->transformToDisplayCoord(
|
||||||
|
wellPathPoints[i] + wellPathSegmentNormals[i] * planeOffsetFromWellPathCenter)));
|
||||||
|
|
||||||
// Normal lines
|
indices.push_back(indexCounter);
|
||||||
for (size_t i = 0; i < pointNormals.size(); i++)
|
indices.push_back(++indexCounter);
|
||||||
|
}
|
||||||
|
// Line along and far away from well in reverse order to create a closed surface.
|
||||||
|
for (int64_t i = (int64_t) wellPathPoints.size()-1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
vertices.push_back(cvf::Vec3f(displayCoordTransform->transformToDisplayCoord(
|
||||||
|
wellPathPoints[i] + wellPathSegmentNormals[i] * (planeOffsetFromWellPathCenter + planeWidth))));
|
||||||
|
|
||||||
|
indices.push_back(indexCounter);
|
||||||
|
indices.push_back(++indexCounter);
|
||||||
|
}
|
||||||
|
indices.pop_back();
|
||||||
|
indices.push_back(0u); // Close surface
|
||||||
|
cvf::ref<cvf::PrimitiveSetIndexedUInt> indexedUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_LINE_LOOP);
|
||||||
|
cvf::ref<cvf::UIntArray> indexArray = new cvf::UIntArray(indices);
|
||||||
|
|
||||||
|
cvf::ref<cvf::DrawableGeo> gridBorderDrawable = new cvf::DrawableGeo();
|
||||||
|
|
||||||
|
indexedUInt->setIndices(indexArray.p());
|
||||||
|
gridBorderDrawable->addPrimitiveSet(indexedUInt.p());
|
||||||
|
|
||||||
|
cvf::ref<cvf::Vec3fArray> vertexArray = new cvf::Vec3fArray(vertices);
|
||||||
|
gridBorderDrawable->setVertexArray(vertexArray.p());
|
||||||
|
drawables[GridBorder] = gridBorderDrawable;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::vector<cvf::Vec3f> vertices;
|
||||||
|
vertices.reserve(gridPoints.size());
|
||||||
|
|
||||||
|
std::vector<cvf::uint> indices;
|
||||||
|
indices.reserve(gridPoints.size());
|
||||||
|
cvf::uint indexCounter = 0;
|
||||||
|
// Normal lines. Start from one to avoid drawing at surface edge.
|
||||||
|
for (size_t i = 1; i < pointNormals.size(); i++)
|
||||||
{
|
{
|
||||||
vertices.push_back(cvf::Vec3f(
|
vertices.push_back(cvf::Vec3f(
|
||||||
displayCoordTransform->transformToDisplayCoord(gridPoints[i] + pointNormals[i] * planeOffsetFromWellPathCenter)));
|
displayCoordTransform->transformToDisplayCoord(gridPoints[i] + pointNormals[i] * planeOffsetFromWellPathCenter)));
|
||||||
@ -115,49 +181,20 @@ cvf::ref<cvf::DrawableGeo> Riv3dWellLogGridGeometryGenerator::createGrid(const c
|
|||||||
indices.push_back(indexCounter++);
|
indices.push_back(indexCounter++);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculateLineSegmentNormals returns normals for the whole well path. Erase the part which is clipped off
|
|
||||||
std::vector<cvf::Vec3d> wellPathSegmentNormals =
|
|
||||||
RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle, wellPathGeometry()->m_wellPathPoints, RigWellPathGeometryTools::POLYLINE);
|
|
||||||
wellPathSegmentNormals.erase(wellPathSegmentNormals.begin(), wellPathSegmentNormals.end() - wellPathPoints.size());
|
|
||||||
|
|
||||||
// Line along and close to well
|
|
||||||
for (size_t i = 0; i < wellPathPoints.size(); i++)
|
|
||||||
{
|
|
||||||
vertices.push_back(cvf::Vec3f(displayCoordTransform->transformToDisplayCoord(
|
|
||||||
wellPathPoints[i] + wellPathSegmentNormals[i] * planeOffsetFromWellPathCenter)));
|
|
||||||
|
|
||||||
indices.push_back(indexCounter);
|
|
||||||
indices.push_back(++indexCounter);
|
|
||||||
}
|
|
||||||
// Indices are added as line segments for the current point and the next point. The last point does not have a next point,
|
|
||||||
// therefore we remove the last line segment
|
|
||||||
indices.pop_back();
|
|
||||||
indices.pop_back();
|
|
||||||
|
|
||||||
// Line along and far away from well
|
|
||||||
for (size_t i = 0; i < wellPathPoints.size(); i++)
|
|
||||||
{
|
|
||||||
vertices.push_back(cvf::Vec3f(displayCoordTransform->transformToDisplayCoord(
|
|
||||||
wellPathPoints[i] + wellPathSegmentNormals[i] * (planeOffsetFromWellPathCenter + planeWidth))));
|
|
||||||
|
|
||||||
indices.push_back(indexCounter);
|
|
||||||
indices.push_back(++indexCounter);
|
|
||||||
}
|
|
||||||
indices.pop_back();
|
|
||||||
indices.pop_back();
|
|
||||||
|
|
||||||
cvf::ref<cvf::PrimitiveSetIndexedUInt> indexedUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_LINES);
|
cvf::ref<cvf::PrimitiveSetIndexedUInt> indexedUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_LINES);
|
||||||
cvf::ref<cvf::UIntArray> indexArray = new cvf::UIntArray(indices);
|
cvf::ref<cvf::UIntArray> indexArray = new cvf::UIntArray(indices);
|
||||||
|
|
||||||
cvf::ref<cvf::DrawableGeo> drawable = new cvf::DrawableGeo();
|
cvf::ref<cvf::DrawableGeo> normalLinesDrawable = new cvf::DrawableGeo();
|
||||||
|
|
||||||
indexedUInt->setIndices(indexArray.p());
|
indexedUInt->setIndices(indexArray.p());
|
||||||
drawable->addPrimitiveSet(indexedUInt.p());
|
normalLinesDrawable->addPrimitiveSet(indexedUInt.p());
|
||||||
|
|
||||||
cvf::ref<cvf::Vec3fArray> vertexArray = new cvf::Vec3fArray(vertices);
|
cvf::ref<cvf::Vec3fArray> vertexArray = new cvf::Vec3fArray(vertices);
|
||||||
drawable->setVertexArray(vertexArray.p());
|
normalLinesDrawable->setVertexArray(vertexArray.p());
|
||||||
|
|
||||||
return drawable;
|
drawables[NormalLines] = normalLinesDrawable;
|
||||||
|
}
|
||||||
|
return drawables;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include "cafPdmPointer.h"
|
#include "cafPdmPointer.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <map>
|
||||||
|
|
||||||
namespace caf
|
namespace caf
|
||||||
{
|
{
|
||||||
@ -42,9 +42,16 @@ class RimWellPath;
|
|||||||
class Riv3dWellLogGridGeometryGenerator : public cvf::Object
|
class Riv3dWellLogGridGeometryGenerator : public cvf::Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum DrawableId
|
||||||
|
{
|
||||||
|
NormalLines = 0,
|
||||||
|
GridBorder = 1,
|
||||||
|
GridBackground = 2
|
||||||
|
};
|
||||||
Riv3dWellLogGridGeometryGenerator(RimWellPath* wellPath);
|
Riv3dWellLogGridGeometryGenerator(RimWellPath* wellPath);
|
||||||
|
|
||||||
cvf::ref<cvf::DrawableGeo> createGrid(const caf::DisplayCoordTransform* displayCoordTransform,
|
std::map<DrawableId, cvf::ref<cvf::DrawableGeo> >
|
||||||
|
createGrid(const caf::DisplayCoordTransform* displayCoordTransform,
|
||||||
const cvf::BoundingBox& wellPathClipBoundingBox,
|
const cvf::BoundingBox& wellPathClipBoundingBox,
|
||||||
double planeAngle,
|
double planeAngle,
|
||||||
double planeOffsetFromWellPathCenter,
|
double planeOffsetFromWellPathCenter,
|
||||||
|
@ -38,6 +38,8 @@
|
|||||||
#include "cvfModelBasicList.h"
|
#include "cvfModelBasicList.h"
|
||||||
#include "cvfPart.h"
|
#include "cvfPart.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -221,9 +223,12 @@ void Riv3dWellLogPlanePartMgr::appendGridToModel(cvf::ModelBasicList*
|
|||||||
const Rim3dWellLogCurveCollection* curveCollection = m_wellPath->rim3dWellLogCurveCollection();
|
const Rim3dWellLogCurveCollection* curveCollection = m_wellPath->rim3dWellLogCurveCollection();
|
||||||
Rim3dWellLogCurveCollection::PlanePosition planePosition = curveCollection->planePosition();
|
Rim3dWellLogCurveCollection::PlanePosition planePosition = curveCollection->planePosition();
|
||||||
|
|
||||||
caf::MeshEffectGenerator meshEffectGen(cvf::Color3f(0.4f, 0.4f, 0.4f));
|
caf::SurfaceEffectGenerator surfaceEffectGen(cvf::Color4f(1.0, 1.0, 1.0, 0.5), caf::PO_1);
|
||||||
|
caf::MeshEffectGenerator gridBorderEffectGen(cvf::Color3f(0.4f, 0.4f, 0.4f));
|
||||||
|
caf::MeshEffectGenerator normalsEffectGen(cvf::Color3f(0.4f, 0.4f, 0.4f));
|
||||||
|
normalsEffectGen.setLineStipple(true);
|
||||||
|
|
||||||
cvf::ref<cvf::Drawable> gridHorizontalDrawable =
|
std::map < Riv3dWellLogGridGeometryGenerator::DrawableId, cvf::ref<cvf::DrawableGeo> > gridDrawables =
|
||||||
m_3dWellLogGridGeometryGenerator->createGrid(displayCoordTransform,
|
m_3dWellLogGridGeometryGenerator->createGrid(displayCoordTransform,
|
||||||
wellPathClipBoundingBox,
|
wellPathClipBoundingBox,
|
||||||
planeAngle(drawPlane),
|
planeAngle(drawPlane),
|
||||||
@ -231,11 +236,21 @@ void Riv3dWellLogPlanePartMgr::appendGridToModel(cvf::ModelBasicList*
|
|||||||
planeWidth(),
|
planeWidth(),
|
||||||
gridIntervalSize);
|
gridIntervalSize);
|
||||||
|
|
||||||
cvf::ref<cvf::Effect> effect = meshEffectGen.generateCachedEffect();
|
std::map < Riv3dWellLogGridGeometryGenerator::DrawableId, cvf::ref<cvf::Effect> > effects;
|
||||||
cvf::ref<cvf::Part> part = createPart(gridHorizontalDrawable.p(), effect.p());
|
effects[Riv3dWellLogGridGeometryGenerator::GridBackground] = surfaceEffectGen.generateCachedEffect();
|
||||||
|
effects[Riv3dWellLogGridGeometryGenerator::GridBorder] = gridBorderEffectGen.generateCachedEffect();
|
||||||
|
effects[Riv3dWellLogGridGeometryGenerator::NormalLines] = normalsEffectGen.generateCachedEffect();
|
||||||
|
cvf::ref<cvf::Effect> normalsEffect = normalsEffectGen.generateCachedEffect();
|
||||||
|
|
||||||
|
for(std::pair< Riv3dWellLogGridGeometryGenerator::DrawableId, cvf::ref<cvf::DrawableGeo> > item : gridDrawables)
|
||||||
|
{
|
||||||
|
Riv3dWellLogGridGeometryGenerator::DrawableId drawableId = item.first;
|
||||||
|
cvf::ref<cvf::DrawableGeo> drawable = item.second;
|
||||||
|
CVF_ASSERT(drawable.notNull());
|
||||||
|
cvf::ref<cvf::Part> part = createPart(drawable.p(), effects[drawableId].p());
|
||||||
if (part.notNull())
|
if (part.notNull())
|
||||||
{
|
{
|
||||||
model->addPart(part.p());
|
model->addPart(part.p());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user