3D Well Log Curves (#2746): Handle set scale.

* Transform to display coordinates *before* calculating normals and generating curves.
This commit is contained in:
Gaute Lindkvist 2018-04-18 11:09:50 +02:00
parent 3303350193
commit 01a1f660e7
4 changed files with 44 additions and 34 deletions

View File

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

View File

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

View File

@ -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)
{

View File

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