mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
3D Well Log Curves (#2746): Handle set scale.
* Transform to display coordinates *before* calculating normals and generating curves.
This commit is contained in:
parent
3303350193
commit
01a1f660e7
@ -107,22 +107,30 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveVerticesAndIndices(const std
|
||||
RimWellPathCollection* wellPathCollection = nullptr;
|
||||
m_wellPath->firstAncestorOrThisOfTypeAsserted(wellPathCollection);
|
||||
|
||||
double maxZClipHeight = wellPathGeometry()->m_wellPathPoints.front().z();
|
||||
cvf::Vec3d clipLocation = wellPathGeometry()->m_wellPathPoints.front();
|
||||
if (wellPathCollection->wellPathClip)
|
||||
{
|
||||
maxZClipHeight = wellPathClipBoundingBox.max().z() + wellPathCollection->wellPathClipZDistance;
|
||||
double clipZDistance = wellPathCollection->wellPathClipZDistance;
|
||||
clipLocation = wellPathClipBoundingBox.max() + clipZDistance * cvf::Vec3d(0, 0, 1);
|
||||
}
|
||||
clipLocation = displayCoordTransform->transformToDisplayCoord(clipLocation);
|
||||
|
||||
std::vector<cvf::Vec3d> wellPathPoints = wellPathGeometry()->m_wellPathPoints;
|
||||
for (cvf::Vec3d& wellPathPoint : wellPathPoints)
|
||||
{
|
||||
wellPathPoint = displayCoordTransform->transformToDisplayCoord(wellPathPoint);
|
||||
}
|
||||
|
||||
std::vector<cvf::Vec3d> wellPathCurveNormals = RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle);
|
||||
std::vector<cvf::Vec3d> wellPathCurveNormals = RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathPoints, planeAngle);
|
||||
|
||||
std::vector<cvf::Vec3d> interpolatedWellPathPoints;
|
||||
std::vector<cvf::Vec3d> interpolatedCurveNormals;
|
||||
// Iterate from bottom of well path and up to be able to stop at given Z max clipping height
|
||||
for (auto md = resultMds.rbegin(); md != resultMds.rend(); md++)
|
||||
{
|
||||
cvf::Vec3d point = wellPathGeometry()->interpolatedPointAlongWellPath(*md);
|
||||
cvf::Vec3d point = wellPathGeometry()->interpolatedVectorAlongWellPath(wellPathPoints, *md);
|
||||
cvf::Vec3d normal = wellPathGeometry()->interpolatedVectorAlongWellPath(wellPathCurveNormals, *md);
|
||||
if (point.z() > maxZClipHeight) break;
|
||||
if (point.z() > clipLocation.z()) break;
|
||||
|
||||
interpolatedWellPathPoints.push_back(point);
|
||||
interpolatedCurveNormals.push_back(normal.getNormalized());
|
||||
@ -162,8 +170,7 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveVerticesAndIndices(const std
|
||||
planeOffsetFromWellPathCenter + (resultValuesForInterpolatedPoints[i] - minResult) * plotRangeToResultRangeFactor;
|
||||
}
|
||||
|
||||
(*vertices)[i] = cvf::Vec3f(
|
||||
displayCoordTransform->transformToDisplayCoord(interpolatedWellPathPoints[i] + scaledResult * interpolatedCurveNormals[i]));
|
||||
(*vertices)[i] = cvf::Vec3f(interpolatedWellPathPoints[i] + scaledResult * interpolatedCurveNormals[i]);
|
||||
}
|
||||
|
||||
std::vector<std::pair<size_t, size_t>> valuesIntervals =
|
||||
|
@ -74,15 +74,26 @@ Riv3dWellLogGridGeometryGenerator::createGrid(const caf::DisplayCoordTransform*
|
||||
return false;
|
||||
}
|
||||
|
||||
for (cvf::Vec3d& wellPathPoint : wellPathPoints)
|
||||
{
|
||||
wellPathPoint = displayCoordTransform->transformToDisplayCoord(wellPathPoint);
|
||||
}
|
||||
|
||||
std::vector<cvf::Vec3d> wellPathSegmentNormals =
|
||||
RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathPoints, planeAngle);
|
||||
|
||||
|
||||
size_t originalWellPathSize = wellPathPoints.size();
|
||||
|
||||
if (wellPathCollection->wellPathClip)
|
||||
{
|
||||
double clipZDistance = wellPathCollection->wellPathClipZDistance;
|
||||
double horizontalLengthAlongWellToClipPoint;
|
||||
double maxZClipHeight = wellPathClipBoundingBox.max().z() + wellPathCollection->wellPathClipZDistance;
|
||||
cvf::Vec3d clipLocation = wellPathClipBoundingBox.max() + clipZDistance * cvf::Vec3d(0, 0, 1);
|
||||
clipLocation = displayCoordTransform->transformToDisplayCoord(clipLocation);
|
||||
size_t indexToFirstVisibleSegment;
|
||||
wellPathPoints = RigWellPath::clipPolylineStartAboveZ(
|
||||
wellPathPoints, maxZClipHeight, &horizontalLengthAlongWellToClipPoint, &indexToFirstVisibleSegment);
|
||||
wellPathPoints, clipLocation.z(), &horizontalLengthAlongWellToClipPoint, &indexToFirstVisibleSegment);
|
||||
}
|
||||
|
||||
if (wellPathPoints.size() < (size_t) 2)
|
||||
@ -91,9 +102,8 @@ Riv3dWellLogGridGeometryGenerator::createGrid(const caf::DisplayCoordTransform*
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculateLineSegmentNormals returns normals for the whole well path. Erase the part which is clipped off
|
||||
std::vector<cvf::Vec3d> wellPathSegmentNormals =
|
||||
RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathGeometry(), planeAngle);
|
||||
// Note that normals are calculated on the full non-clipped well path to increase the likelihood of creating good normals
|
||||
// for the end points of the curve. So we need to clip the remainder here.
|
||||
wellPathSegmentNormals.erase(wellPathSegmentNormals.begin(), wellPathSegmentNormals.end() - wellPathPoints.size());
|
||||
|
||||
{
|
||||
@ -106,10 +116,10 @@ Riv3dWellLogGridGeometryGenerator::createGrid(const caf::DisplayCoordTransform*
|
||||
// Vertices are used for both surface and border
|
||||
for (size_t i = 0; i < wellPathPoints.size(); i++)
|
||||
{
|
||||
vertices.push_back(cvf::Vec3f(displayCoordTransform->transformToDisplayCoord(
|
||||
wellPathPoints[i] + wellPathSegmentNormals[i] * planeOffsetFromWellPathCenter)));
|
||||
vertices.push_back(cvf::Vec3f(displayCoordTransform->transformToDisplayCoord(
|
||||
wellPathPoints[i] + wellPathSegmentNormals[i] * (planeOffsetFromWellPathCenter + planeWidth))));
|
||||
vertices.push_back(cvf::Vec3f(
|
||||
wellPathPoints[i] + wellPathSegmentNormals[i] * planeOffsetFromWellPathCenter));
|
||||
vertices.push_back(cvf::Vec3f(
|
||||
wellPathPoints[i] + wellPathSegmentNormals[i] * (planeOffsetFromWellPathCenter + planeWidth)));
|
||||
backgroundIndices.push_back((cvf::uint) (2 * i));
|
||||
backgroundIndices.push_back((cvf::uint) (2 * i + 1));
|
||||
}
|
||||
@ -177,7 +187,7 @@ Riv3dWellLogGridGeometryGenerator::createGrid(const caf::DisplayCoordTransform*
|
||||
double md = lastMd;
|
||||
while (md >= firstMd)
|
||||
{
|
||||
cvf::Vec3d point = wellPathGeometry()->interpolatedPointAlongWellPath(md);
|
||||
cvf::Vec3d point = wellPathGeometry()->interpolatedVectorAlongWellPath(wellPathPoints, md);
|
||||
cvf::Vec3d curveNormal = wellPathGeometry()->interpolatedVectorAlongWellPath(wellPathSegmentNormals, md);
|
||||
interpolatedGridPoints.push_back(point);
|
||||
interpolatedGridCurveNormals.push_back(curveNormal.getNormalized());
|
||||
@ -193,11 +203,9 @@ Riv3dWellLogGridGeometryGenerator::createGrid(const caf::DisplayCoordTransform*
|
||||
// Normal lines. Start from one to avoid drawing at surface edge.
|
||||
for (size_t i = 1; i < interpolatedGridCurveNormals.size(); i++)
|
||||
{
|
||||
vertices.push_back(cvf::Vec3f(
|
||||
displayCoordTransform->transformToDisplayCoord(interpolatedGridPoints[i] + interpolatedGridCurveNormals[i] * planeOffsetFromWellPathCenter)));
|
||||
vertices.push_back(cvf::Vec3f(interpolatedGridPoints[i] + interpolatedGridCurveNormals[i] * planeOffsetFromWellPathCenter));
|
||||
|
||||
vertices.push_back(cvf::Vec3f(displayCoordTransform->transformToDisplayCoord(
|
||||
interpolatedGridPoints[i] + interpolatedGridCurveNormals[i] * (planeOffsetFromWellPathCenter + planeWidth))));
|
||||
vertices.push_back(cvf::Vec3f(interpolatedGridPoints[i] + interpolatedGridCurveNormals[i] * (planeOffsetFromWellPathCenter + planeWidth)));
|
||||
|
||||
indices.push_back(indexCounter++);
|
||||
indices.push_back(indexCounter++);
|
||||
|
@ -29,22 +29,18 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<cvf::Vec3d> RigWellPathGeometryTools::calculateLineSegmentNormals(const RigWellPath* wellPathGeometry,
|
||||
std::vector<cvf::Vec3d> RigWellPathGeometryTools::calculateLineSegmentNormals(const std::vector<cvf::Vec3d>& vertices,
|
||||
double planeAngle)
|
||||
{
|
||||
std::vector<cvf::Vec3d> pointNormals;
|
||||
|
||||
if (!wellPathGeometry) return pointNormals;
|
||||
|
||||
const std::vector<cvf::Vec3d>& vertices = wellPathGeometry->wellPathPoints();
|
||||
|
||||
if (vertices.empty()) return pointNormals;
|
||||
|
||||
pointNormals.reserve(vertices.size());
|
||||
|
||||
cvf::Vec3d up(0, 0, 1);
|
||||
|
||||
cvf::Vec3d dominantDirection = estimateDominantDirectionInXYPlane(wellPathGeometry);
|
||||
cvf::Vec3d dominantDirection = estimateDominantDirectionInXYPlane(vertices);
|
||||
|
||||
const cvf::Vec3d projectionPlaneNormal = (up ^ dominantDirection).getNormalized();
|
||||
CVF_ASSERT(projectionPlaneNormal * dominantDirection <= std::numeric_limits<double>::epsilon());
|
||||
@ -130,13 +126,12 @@ std::vector<cvf::Vec3d> RigWellPathGeometryTools::interpolateUndefinedNormals(co
|
||||
return interpolated;
|
||||
}
|
||||
|
||||
cvf::Vec3d RigWellPathGeometryTools::estimateDominantDirectionInXYPlane(const RigWellPath* wellPathGeometry)
|
||||
cvf::Vec3d RigWellPathGeometryTools::estimateDominantDirectionInXYPlane(const std::vector<cvf::Vec3d>& vertices)
|
||||
{
|
||||
cvf::Vec3d directionSum(0, 0, 0);
|
||||
const std::vector<cvf::Vec3d>& points = wellPathGeometry->m_wellPathPoints;
|
||||
for (size_t i = 1; i < points.size(); ++i)
|
||||
cvf::Vec3d directionSum(0, 0, 0);
|
||||
for (size_t i = 1; i < vertices.size(); ++i)
|
||||
{
|
||||
cvf::Vec3d vec = points[i] - points[i - 1];
|
||||
cvf::Vec3d vec = vertices[i] - vertices[i - 1];
|
||||
vec.z() = 0.0;
|
||||
if (directionSum.length() > 0.0 && (directionSum * vec) < 0.0)
|
||||
{
|
||||
|
@ -38,11 +38,11 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
static std::vector<cvf::Vec3d> calculateLineSegmentNormals(const RigWellPath* wellPathGeometry,
|
||||
static std::vector<cvf::Vec3d> calculateLineSegmentNormals(const std::vector<cvf::Vec3d>& vertices,
|
||||
double angle);
|
||||
private:
|
||||
static std::vector<cvf::Vec3d> interpolateUndefinedNormals(const cvf::Vec3d& planeNormal,
|
||||
const std::vector<cvf::Vec3d>& normals,
|
||||
const std::vector<cvf::Vec3d>& vertices);
|
||||
static cvf::Vec3d estimateDominantDirectionInXYPlane(const RigWellPath* wellPathGeometry);
|
||||
static cvf::Vec3d estimateDominantDirectionInXYPlane(const std::vector<cvf::Vec3d>& vertices);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user